Re: USB-MSD non-functional after merging v5.1 to v6.x (seems to be internal USB stack issue?)

2021-09-02 Thread kra...@redhat.com
  Hi,

> At some point during implementation of the STM USB stack must have run
> into the same problem with the communications choking during MSD init.
> And at the time (which involved a LOT of wireshark comparisons with a
> real USB drive on the host and on the DCW2 Rpi2 stack) I'd added the
> QEMU_PACKED directive to the usb_msd_csw struct.

> Thoughts?

Send a patch adding the QEMU_PACKED,
that should indeed be the correct fix.

thanks,
  Gerd




Re: [PATCH v2 01/22] target/riscv: Fix trap cause for RV32 HS-mode CSR access from RV64 HS-mode

2021-09-02 Thread Alistair Francis
On Thu, Sep 2, 2021 at 9:36 PM Anup Patel  wrote:
>
> We should be returning illegal instruction trap when RV64 HS-mode tries
> to access RV32 HS-mode CSR.
>
> Fixes: d6f20dacea51 ("target/riscv: Fix 32-bit HS mode access permissions")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 50a2c3a3b4..1f13d1042d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -181,7 +181,7 @@ static RISCVException hmode(CPURISCVState *env, int csrno)
>  static RISCVException hmode32(CPURISCVState *env, int csrno)
>  {
>  if (!riscv_cpu_is_32bit(env)) {
> -if (riscv_cpu_virt_enabled(env)) {
> +if (!riscv_cpu_virt_enabled(env)) {
>  return RISCV_EXCP_ILLEGAL_INST;
>  } else {
>  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> --
> 2.25.1
>
>



Re: USB-MSD non-functional after merging v5.1 to v6.x (seems to be internal USB stack issue?)

2021-09-02 Thread VintagePC
Well... the plot thickens. I have found the smoking gun.

At some point during implementation of the STM USB stack must have run into the 
same problem with the communications choking during MSD init. And at the time 
(which involved a LOT of wireshark comparisons with a real USB drive on the 
host and on the DCW2 Rpi2 stack) I'd added the QEMU_PACKED directive to the 
usb_msd_csw struct.

Naturally, when the definitions were relocated to a header, that was lost when 
resolving the merge conflict because I wasn't paying attention. (D'oh!)

So while it's working again... the question still remains why I had to make 
this tweak in the first place - so I dug further:

I just re-compared with the MSD setup of a real drive on the PC. The status 
section of the MSD is only a single byte for the real drive but is 4 bytes in 
the packet received by the guest without the PACKED directive. Wireshark also 
cannot decode this "oversize" packet properly, which seems to further suggest  
that this may indeed be an actual bug in the MSD implementation - naturally it 
would only manifest on systems/compilers where the data alignment precipitates 
this problem.

Further code inspection suggests this originates with the following line in 
usb-storage.c:
> len = MIN(sizeof(s->csw), p->iov.size);
specifically, if the iov.size is > than the MSD CSW. And that's where my 
knowledge of the QEMU USB system ends and I defer to those more knowledgeable. 
I'm guessing this might mean that things are fine if the receiving endpoint 
configures itself to exactly the expected CSW size - but breaks if the endpoint 
is configured with a larger receive buffer. At least for ARM kernel being run 
this isn't custom code and is part of the generic HAL and USB stack STM offers 
- so I have a hard time believing this is an unusual practice.

I even went so far as to eliminate dev-storage from the picture entirely and 
use USB-host to connect a real physical USB drive with the simulated platform - 
and again, the wireshark capture reveals that the CSW packet size is a single 
byte as the "correct" behaviour regardless of how the device sets up its 
receive buffers.

Thoughts?

~ VintagePC




RE: [RFC][PATCH v1 00/10] Enable encrypted guest memory access in QEMU

2021-09-02 Thread Yao, Yuan
>-Original Message-
>From: Ashish Kalra 
>Sent: Thursday, September 02, 2021 22:05
>To: yuan@linux.intel.com
>Cc: thomas.lenda...@amd.com; arm...@redhat.com; ashish.ka...@amd.com; 
>brijesh.si...@amd.com;
>dgilb...@redhat.com; ehabk...@redhat.com; Yamahata, Isaku 
>; k...@vger.kernel.org;
>m...@redhat.com; mtosa...@redhat.com; pbonz...@redhat.com; 
>qemu-devel@nongnu.org; Yao, Yuan
>
>Subject: [RFC][PATCH v1 00/10] Enable encrypted guest memory access in QEMU
>
>> - We introduce another new vm level ioctl focus on the encrypted
>> guest memory accessing:
>>
>> KVM_MEMORY_ENCRYPT_{READ,WRITE}_MEMORY
>>
>> struct kvm_rw_memory rw;
>> rw.addr = gpa_OR_hva;
>> rw.buf = (__u64)src;
>> rw.len = len;
>> kvm_vm_ioctl(kvm_state,
>>  KVM_MEMORY_ENCRYPT_{READ,WRITE}_MEMORY,
>>  );
>>
>> This new ioctl has more neutral and general name for its
>> purpose, the debugging support of AMD SEV and INTEL TDX
>> can be covered by a unify QEMU implementation on x86 with this
>> ioctl. Although only INTEL TD guest is supported in this series,
>> AMD SEV could be also supported with implementation of this
>> ioctl in KVM, plus small modifications in QEMU to enable the
>> unify part.
>
>A general comment, we have sev_ioctl() interface for SEV guests and
>probably this new vm level ioctl will not work for us.
>
>It probably makes more sense to do this TDX/SEV level abstraction
>using the Memory Region's ram_debug_ops, which can point these to
>TDX specific vm level ioctl and SEV specific ioctl at the lowest
>level of this interface.
>
Hi Ashish,

Yes, this new ioctl is now working as the low-level interface for 
Memory Region's ram_debug_ops. SEV can use 
kvm_setup_set_memory_region_debug_ops() to install a new
callback to KVM for installing SEV only low-level implementation,
then call kvm_set_memory_region_debug_ops() to do Memory
Region's ram_debug_ops installation later.


>Thanks,
>Ashish



Re: [RFC 0/5] VirtIO RDMA

2021-09-02 Thread Jason Wang
On Thu, Sep 2, 2021 at 9:07 PM Junji Wei  wrote:
>
> Hi all,
>
> This RFC aims to reopen the discussion of Virtio RDMA.
> Now this is based on Yuval Shaia's RFC "VirtIO RDMA"
> which implemented a frame for Virtio RDMA and a simple
> control path (Not sure if Yuval Shaia has any further
> plan for it).
>
> We try to extend this work and implement a simple
> data-path and a completed control path. Now this can
> work with SEND, RECV and REG_MR in kernel. There is a
> simple test module in this patch that can communicate
> with ibv_rc_pingpong in rdma-core.
>
> During doing this work, we have found some problems and
> would like to ask for some suggestions from community:

I think it would be beneficial if you can post a spec patch.

Thanks




Re: [PATCH v3 21/30] target/ppc: Introduce PowerPCCPUClass::has_work()

2021-09-02 Thread David Gibson
On Thu, Sep 02, 2021 at 06:15:34PM +0200, Philippe Mathieu-Daudé wrote:
> Each POWER cpu has its own has_work() implementation. Instead of
> overloading CPUClass on each PowerPCCPUClass init, register the
> generic ppc_cpu_has_work() handler, and have it call the POWER
> specific has_work().

I don't quite see the rationale for introducing a second layer of
indirection here.  What's wrong with switching the base has_work for
each cpu variant?

> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/ppc/cpu-qom.h  |  3 +++
>  target/ppc/cpu_init.c | 26 ++
>  2 files changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
> index 5800fa324e8..ff2bafcde6f 100644
> --- a/target/ppc/cpu-qom.h
> +++ b/target/ppc/cpu-qom.h
> @@ -189,6 +189,9 @@ struct PowerPCCPUClass {
>  int bfd_mach;
>  uint32_t l1_dcache_size, l1_icache_size;
>  #ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_TCG
> +bool (*has_work)(CPUState *cpu);
> +#endif /* CONFIG_TCG */
>  unsigned int gdb_num_sprs;
>  const char *gdb_spr_xml;
>  #endif
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index e2e721c2b81..bbad16cc1ec 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -7583,6 +7583,7 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, 
> uint32_t pvr)
>  return false;
>  }
>  
> +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>  static bool cpu_has_work_POWER7(CPUState *cs)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -7616,12 +7617,12 @@ static bool cpu_has_work_POWER7(CPUState *cs)
>  return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
>  }
>  }
> +#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
>  
>  POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(oc);
>  PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> -CPUClass *cc = CPU_CLASS(oc);
>  
>  dc->fw_name = "PowerPC,POWER7";
>  dc->desc = "POWER7";
> @@ -7630,7 +7631,6 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>  pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
>  pcc->init_proc = init_proc_POWER7;
>  pcc->check_pow = check_pow_nocheck;
> -cc->has_work = cpu_has_work_POWER7;
>  pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
> PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
> PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
> @@ -7673,6 +7673,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>  pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
>  pcc->mmu_model = POWERPC_MMU_2_06;
>  #if defined(CONFIG_SOFTMMU)
> +pcc->has_work = cpu_has_work_POWER7;
>  pcc->hash64_opts = _hash64_opts_POWER7;
>  pcc->lrg_decr_bits = 32;
>  #endif
> @@ -7743,6 +7744,7 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, 
> uint32_t pvr)
>  return false;
>  }
>  
> +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>  static bool cpu_has_work_POWER8(CPUState *cs)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -7784,12 +7786,12 @@ static bool cpu_has_work_POWER8(CPUState *cs)
>  return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
>  }
>  }
> +#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
>  
>  POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(oc);
>  PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> -CPUClass *cc = CPU_CLASS(oc);
>  
>  dc->fw_name = "PowerPC,POWER8";
>  dc->desc = "POWER8";
> @@ -7798,7 +7800,6 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
>  pcc->init_proc = init_proc_POWER8;
>  pcc->check_pow = check_pow_nocheck;
> -cc->has_work = cpu_has_work_POWER8;
>  pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
> PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
> PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
> @@ -7848,6 +7849,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
> LPCR_P8_PECE3 | LPCR_P8_PECE4;
>  pcc->mmu_model = POWERPC_MMU_2_07;
>  #if defined(CONFIG_SOFTMMU)
> +pcc->has_work = cpu_has_work_POWER8;
>  pcc->hash64_opts = _hash64_opts_POWER7;
>  pcc->lrg_decr_bits = 32;
>  pcc->n_host_threads = 8;
> @@ -7941,6 +7943,7 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, 
> uint32_t pvr)
>  return false;
>  }
>  
> +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>  static bool cpu_has_work_POWER9(CPUState *cs)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -7998,12 +8001,12 @@ static bool cpu_has_work_POWER9(CPUState *cs)
>  return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
>  }
>  }
> +#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
>  
>  POWERPC_FAMILY(POWER9)(ObjectClass 

Re: [PATCH 17/24] target/ppc: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread David Gibson
On Thu, Sep 02, 2021 at 05:17:08PM +0200, Philippe Mathieu-Daudé wrote:
> Restrict cpu_exec_interrupt() and its callees to sysemu.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: David Gibson 

> ---
>  target/ppc/cpu.h |  4 ++--
>  target/ppc/cpu_init.c|  2 +-
>  target/ppc/excp_helper.c | 21 +++--
>  3 files changed, 6 insertions(+), 21 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 500205229c0..362e7c4c5c7 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1254,8 +1254,6 @@ DECLARE_OBJ_CHECKERS(PPCVirtualHypervisor, 
> PPCVirtualHypervisorClass,
>   PPC_VIRTUAL_HYPERVISOR, TYPE_PPC_VIRTUAL_HYPERVISOR)
>  #endif /* CONFIG_USER_ONLY */
>  
> -void ppc_cpu_do_interrupt(CPUState *cpu);
> -bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
> @@ -1271,6 +1269,8 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, 
> CPUState *cs,
>  int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
> +void ppc_cpu_do_interrupt(CPUState *cpu);
> +bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
>  extern const VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index ad7abc6041a..6aad01d1d3a 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -9014,10 +9014,10 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
>  
>  static const struct TCGCPUOps ppc_tcg_ops = {
>.initialize = ppc_translate_init,
> -  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
>.tlb_fill = ppc_cpu_tlb_fill,
>  
>  #ifndef CONFIG_USER_ONLY
> +  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
>.do_interrupt = ppc_cpu_do_interrupt,
>.cpu_exec_enter = ppc_cpu_exec_enter,
>.cpu_exec_exit = ppc_cpu_exec_exit,
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 7b6ac16eef7..d7e32ee107e 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -40,24 +40,8 @@
>  
>  
> /*/
>  /* Exception processing */
> -#if defined(CONFIG_USER_ONLY)
> -void ppc_cpu_do_interrupt(CPUState *cs)
> -{
> -PowerPCCPU *cpu = POWERPC_CPU(cs);
> -CPUPPCState *env = >env;
> +#if !defined(CONFIG_USER_ONLY)
>  
> -cs->exception_index = POWERPC_EXCP_NONE;
> -env->error_code = 0;
> -}
> -
> -static void ppc_hw_interrupt(CPUPPCState *env)
> -{
> -CPUState *cs = env_cpu(env);
> -
> -cs->exception_index = POWERPC_EXCP_NONE;
> -env->error_code = 0;
> -}
> -#else /* defined(CONFIG_USER_ONLY) */
>  static inline void dump_syscall(CPUPPCState *env)
>  {
>  qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
> @@ -1113,7 +1097,6 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, 
> target_ulong vector)
>  
>  powerpc_set_excp_state(cpu, vector, msr);
>  }
> -#endif /* !CONFIG_USER_ONLY */
>  
>  bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -1130,6 +1113,8 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int 
> interrupt_request)
>  return false;
>  }
>  
> +#endif /* !CONFIG_USER_ONLY */
> +
>  #if defined(DEBUG_OP)
>  static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
>  {

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v3 20/30] target/ppc: Restrict has_work() handler to sysemu and TCG

2021-09-02 Thread David Gibson
On Thu, Sep 02, 2021 at 06:15:33PM +0200, Philippe Mathieu-Daudé wrote:
> Restrict has_work() to TCG sysemu.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: David Gibson 

> ---
>  target/ppc/cpu_init.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index 6aad01d1d3a..e2e721c2b81 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -8790,6 +8790,7 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
>  cpu->env.nip = value;
>  }
>  
> +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>  static bool ppc_cpu_has_work(CPUState *cs)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -8797,6 +8798,7 @@ static bool ppc_cpu_has_work(CPUState *cs)
>  
>  return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
>  }
> +#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
>  
>  static void ppc_cpu_reset(DeviceState *dev)
>  {
> @@ -9017,6 +9019,7 @@ static const struct TCGCPUOps ppc_tcg_ops = {
>.tlb_fill = ppc_cpu_tlb_fill,
>  
>  #ifndef CONFIG_USER_ONLY
> +  .has_work = ppc_cpu_has_work,
>.cpu_exec_interrupt = ppc_cpu_exec_interrupt,
>.do_interrupt = ppc_cpu_do_interrupt,
>.cpu_exec_enter = ppc_cpu_exec_enter,
> @@ -9042,7 +9045,6 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
> *data)
>  device_class_set_parent_reset(dc, ppc_cpu_reset, >parent_reset);
>  
>  cc->class_by_name = ppc_cpu_class_by_name;
> -cc->has_work = ppc_cpu_has_work;
>  cc->dump_state = ppc_cpu_dump_state;
>  cc->set_pc = ppc_cpu_set_pc;
>  cc->gdb_read_register = ppc_cpu_gdb_read_register;

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[PATCH v3 39/43] bsd-user: Refactor load_elf_sections and is_target_elf_binary

2021-09-02 Thread imp
From: Warner Losh 

Factor out load_elf_sections and is_target_elf_binary out of
load_elf_interp.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 344 +
 1 file changed, 158 insertions(+), 186 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3660961582..142a5bfac2 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -36,6 +36,8 @@ abi_ulong target_stksiz;
 abi_ulong target_stkbas;
 
 static int elf_core_dump(int signr, CPUArchState *env);
+static int load_elf_sections(const struct elfhdr *hdr, struct elf_phdr *phdr,
+int fd, abi_ulong rbase, abi_ulong *baddrp);
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
@@ -271,16 +273,10 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
  abi_ulong *interp_load_addr)
 {
 struct elf_phdr *elf_phdata  =  NULL;
-struct elf_phdr *eppnt;
-abi_ulong load_addr = 0;
-int load_addr_set = 0;
+abi_ulong rbase;
 int retval;
-abi_ulong last_bss, elf_bss;
-abi_ulong error;
-int i;
+abi_ulong baddr, error;
 
-elf_bss = 0;
-last_bss = 0;
 error = 0;
 
 bswap_ehdr(interp_elf_ex);
@@ -325,93 +321,33 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 }
 bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
 
+rbase = 0;
 if (interp_elf_ex->e_type == ET_DYN) {
 /*
  * In order to avoid hardcoding the interpreter load
  * address in qemu, we allocate a big enough memory zone.
  */
-error = target_mmap(0, INTERP_MAP_SIZE, PROT_NONE,
+rbase = target_mmap(0, INTERP_MAP_SIZE, PROT_NONE,
 MAP_PRIVATE | MAP_ANON, -1, 0);
-if (error == -1) {
+if (rbase == -1) {
 perror("mmap");
 exit(-1);
 }
-load_addr = error;
-load_addr_set = 1;
-}
-
-eppnt = elf_phdata;
-for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++)
-if (eppnt->p_type == PT_LOAD) {
-int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
-int elf_prot = 0;
-abi_ulong vaddr = 0;
-abi_ulong k;
-
-if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
-if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
-if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
-if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
-elf_type |= MAP_FIXED;
-vaddr = eppnt->p_vaddr;
-}
-error = target_mmap(load_addr + TARGET_ELF_PAGESTART(vaddr),
-eppnt->p_filesz + 
TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
-elf_prot,
-elf_type,
-interpreter_fd,
-eppnt->p_offset - 
TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
-
-if (error == -1) {
-/* Real error */
-close(interpreter_fd);
-free(elf_phdata);
-return ~((abi_ulong)0UL);
-}
-
-if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
-load_addr = error;
-load_addr_set = 1;
-}
-
-/*
- * Find the end of the file  mapping for this phdr, and keep
- * track of the largest address we see for this.
- */
-k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
-if (k > elf_bss) elf_bss = k;
+}
 
-/*
- * Do the same thing for the memory mapping - between
- * elf_bss and last_bss is the bss section.
- */
-k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
-if (k > last_bss) last_bss = k;
-}
+error = load_elf_sections(interp_elf_ex, elf_phdata, interpreter_fd, rbase,
+);
+if (error != 0) {
+perror("load_elf_sections");
+exit(-1);
+}
 
 /* Now use mmap to map the library into memory. */
-
 close(interpreter_fd);
-
-/*
- * Now fill out the bss section.  First pad the last page up
- * to the page boundary, and then perform a mmap to make sure
- * that there are zeromapped pages up to and including the last
- * bss page.
- */
-padzero(elf_bss, last_bss);
-elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What 
we have mapped so far */
-
-/* Map the last of the bss segment */
-if (last_bss > elf_bss) {
-target_mmap(elf_bss, last_bss - elf_bss,
-PROT_READ | PROT_WRITE | PROT_EXEC,
-MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-}
 free(elf_phdata);
 
-*interp_load_addr = load_addr;
-return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
+

[PATCH v3 35/43] bsd-user: Add target_arch_reg to describe a target's register set

2021-09-02 Thread imp
From: Warner Losh 

target_reg_t is the normal register. target_fpreg_t is the floating
point registers. target_copy_regs copies the registers out of CPU
context for things like core dumps.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/target_arch_reg.h   | 82 +++
 bsd-user/x86_64/target_arch_reg.h | 92 +++
 2 files changed, 174 insertions(+)
 create mode 100644 bsd-user/i386/target_arch_reg.h
 create mode 100644 bsd-user/x86_64/target_arch_reg.h

diff --git a/bsd-user/i386/target_arch_reg.h b/bsd-user/i386/target_arch_reg.h
new file mode 100644
index 00..1fce1daf01
--- /dev/null
+++ b/bsd-user/i386/target_arch_reg.h
@@ -0,0 +1,82 @@
+/*
+ *  FreeBSD i386 register structures
+ *
+ *  Copyright (c) 2015 Stacey Son
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_REG_H_
+#define _TARGET_ARCH_REG_H_
+
+/* See sys/i386/include/reg.h */
+typedef struct target_reg {
+uint32_tr_fs;
+uint32_tr_es;
+uint32_tr_ds;
+uint32_tr_edi;
+uint32_tr_esi;
+uint32_tr_ebp;
+uint32_tr_isp;
+uint32_tr_ebx;
+uint32_tr_edx;
+uint32_tr_ecx;
+uint32_tr_eax;
+uint32_tr_trapno;
+uint32_tr_err;
+uint32_tr_eip;
+uint32_tr_cs;
+uint32_tr_eflags;
+uint32_tr_esp;
+uint32_tr_ss;
+uint32_tr_gs;
+} target_reg_t;
+
+typedef struct target_fpreg {
+uint32_tfpr_env[7];
+uint8_t fpr_acc[8][10];
+uint32_tfpr_ex_sw;
+uint8_t fpr_pad[64];
+} target_fpreg_t;
+
+static inline void target_copy_regs(target_reg_t *regs, const CPUX86State *env)
+{
+
+regs->r_fs = env->segs[R_FS].selector & 0x;
+regs->r_es = env->segs[R_ES].selector & 0x;
+regs->r_ds = env->segs[R_DS].selector & 0x;
+
+regs->r_edi = env->regs[R_EDI];
+regs->r_esi = env->regs[R_ESI];
+regs->r_ebp = env->regs[R_EBP];
+/* regs->r_isp = env->regs[R_ISP]; XXX */
+regs->r_ebx = env->regs[R_EBX];
+regs->r_edx = env->regs[R_EDX];
+regs->r_ecx = env->regs[R_ECX];
+regs->r_eax = env->regs[R_EAX];
+/* regs->r_trapno = env->regs[R_TRAPNO]; XXX */
+regs->r_err = env->error_code;  /* XXX ? */
+regs->r_eip = env->eip;
+
+regs->r_cs = env->segs[R_CS].selector & 0x;
+
+regs->r_eflags = env->eflags;
+regs->r_esp = env->regs[R_ESP];
+
+regs->r_ss = env->segs[R_SS].selector & 0x;
+regs->r_gs = env->segs[R_GS].selector & 0x;
+}
+
+#endif /* !_TARGET_ARCH_REG_H_ */
diff --git a/bsd-user/x86_64/target_arch_reg.h 
b/bsd-user/x86_64/target_arch_reg.h
new file mode 100644
index 00..00e9624517
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_reg.h
@@ -0,0 +1,92 @@
+/*
+ *  FreeBSD amd64 register structures
+ *
+ *  Copyright (c) 2015 Stacey Son
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_REG_H_
+#define _TARGET_ARCH_REG_H_
+
+/* See sys/amd64/include/reg.h */
+typedef struct target_reg {
+uint64_tr_r15;
+uint64_tr_r14;
+uint64_tr_r13;
+uint64_tr_r12;
+uint64_tr_r11;
+uint64_tr_r10;
+uint64_tr_r9;
+uint64_tr_r8;
+uint64_tr_rdi;
+uint64_tr_rsi;
+uint64_tr_rbp;
+uint64_tr_rbx;
+uint64_tr_rdx;
+uint64_tr_rcx;
+uint64_tr_rax;
+uint32_tr_trapno;
+uint16_tr_fs;
+uint16_tr_gs;
+

[PATCH v3 42/43] bsd-user: Add '-0 argv0' option to bsd-user/main.c

2021-09-02 Thread imp
From: Colin Percival 

Previously it was impossible to emulate a program with a file name
different from its argv[0].  With this change, you can run
qemu -0 fakename realname args
which runs the program "realname" with an argv of "fakename args".

Signed-off-by: Colin Percival 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 88244eb8fe..1602a02aba 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -243,6 +243,7 @@ int main(int argc, char **argv)
 char **target_environ, **wrk;
 envlist_t *envlist = NULL;
 bsd_type = HOST_DEFAULT_BSD_TYPE;
+char *argv0 = NULL;
 
 adjust_ssize();
 
@@ -367,6 +368,8 @@ int main(int argc, char **argv)
 do_strace = 1;
 } else if (!strcmp(r, "trace")) {
 trace_opt_parse(optarg);
+} else if (!strcmp(r, "0")) {
+argv0 = argv[optind++];
 } else {
 usage();
 }
@@ -390,6 +393,9 @@ int main(int argc, char **argv)
 usage();
 }
 filename = argv[optind];
+if (argv0) {
+argv[optind] = argv0;
+}
 
 if (!trace_init_backends()) {
 exit(1);
-- 
2.32.0




[PATCH v3 28/43] bsd-user: Move stack initializtion into a per-os file.

2021-09-02 Thread imp
From: Warner Losh 

Move all of the stack initialization into target_os_stack.h. Each BSD
sets up processes a little differently.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_stack.h | 181 +
 bsd-user/netbsd/target_os_stack.h  |  56 +
 bsd-user/openbsd/target_os_stack.h |  56 +
 3 files changed, 293 insertions(+)
 create mode 100644 bsd-user/freebsd/target_os_stack.h
 create mode 100644 bsd-user/netbsd/target_os_stack.h
 create mode 100644 bsd-user/openbsd/target_os_stack.h

diff --git a/bsd-user/freebsd/target_os_stack.h 
b/bsd-user/freebsd/target_os_stack.h
new file mode 100644
index 00..1bb1a2bf56
--- /dev/null
+++ b/bsd-user/freebsd/target_os_stack.h
@@ -0,0 +1,181 @@
+/*
+ *  FreeBSD setup_initial_stack() implementation.
+ *
+ *  Copyright (c) 2013-14 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_STACK_H_
+#define _TARGET_OS_STACK_H_
+
+#include 
+#include "target_arch_sigtramp.h"
+#include "qemu/guest-random.h"
+
+/*
+ * The inital FreeBSD stack is as follows:
+ * (see kern/kern_exec.c exec_copyout_strings() )
+ *
+ *  Hi Address -> char **ps_argvstr  (struct ps_strings for ps, w, etc.)
+ *unsigned ps_nargvstr
+ *char **ps_envstr
+ *  PS_STRINGS -> unsigned ps_nenvstr
+ *
+ *machine dependent sigcode (sv_sigcode of size
+ *   sv_szsigcode)
+ *
+ *execpath  (absolute image path for rtld)
+ *
+ *SSP Canary(sizeof(long) * 8)
+ *
+ *page sizes array  (usually sizeof(u_long) )
+ *
+ *  "destp" ->argv, env strings (up to 262144 bytes)
+ */
+static inline int setup_initial_stack(struct bsd_binprm *bprm,
+abi_ulong *ret_addr, abi_ulong *stringp)
+{
+int i;
+abi_ulong stack_hi_addr;
+size_t execpath_len, stringspace;
+abi_ulong destp, argvp, envp, p;
+struct target_ps_strings ps_strs;
+char canary[sizeof(abi_long) * 8];
+
+stack_hi_addr = p = target_stkbas + target_stksiz;
+
+/* Save some space for ps_strings. */
+p -= sizeof(struct target_ps_strings);
+
+/* Add machine depedent sigcode. */
+p -= TARGET_SZSIGCODE;
+if (setup_sigtramp(p, (unsigned)offsetof(struct target_sigframe, sf_uc),
+TARGET_FREEBSD_NR_sigreturn)) {
+errno = EFAULT;
+return -1;
+}
+if (bprm->fullpath) {
+execpath_len = strlen(bprm->fullpath) + 1;
+p -= roundup(execpath_len, sizeof(abi_ulong));
+if (memcpy_to_target(p, bprm->fullpath, execpath_len)) {
+errno = EFAULT;
+return -1;
+}
+}
+/* Add canary for SSP. */
+qemu_guest_getrandom_nofail(canary, sizeof(canary));
+p -= roundup(sizeof(canary), sizeof(abi_ulong));
+if (memcpy_to_target(p, canary, sizeof(canary))) {
+errno = EFAULT;
+return -1;
+}
+/* Add page sizes array. */
+p -= sizeof(abi_ulong);
+if (put_user_ual(TARGET_PAGE_SIZE, p)) {
+errno = EFAULT;
+return -1;
+}
+/*
+ * Deviate from FreeBSD stack layout: force stack to new page here
+ * so that signal trampoline is not sharing the page with user stack
+ * frames. This is actively harmful in qemu as it marks pages with
+ * code it translated as read-only, which is somewhat problematic
+ * for user trying to use the stack as intended.
+ */
+p = rounddown(p, TARGET_PAGE_SIZE);
+
+/* Calculate the string space needed */
+stringspace = 0;
+for (i = 0; i < bprm->argc; ++i) {
+stringspace += strlen(bprm->argv[i]) + 1;
+}
+for (i = 0; i < bprm->envc; ++i) {
+stringspace += strlen(bprm->envp[i]) + 1;
+}
+if (stringspace > TARGET_ARG_MAX) {
+errno = ENOMEM;
+return -1;
+}
+/* Make room for the argv and envp strings */
+destp = rounddown(p - stringspace, sizeof(abi_ulong));
+p = argvp = destp - (bprm->argc + bprm->envc + 2) * sizeof(abi_ulong);
+/* Remember the strings pointer */
+if (stringp) {
+*stringp = destp;
+}
+/*
+ * Add argv strings.  Note that the argv[] vectors are added by
+ * loader_build_argptr()
+ */
+/* XXX need to make room for 

[PATCH v3 24/43] bsd-user: Create target specific vmparam.h

2021-09-02 Thread imp
From: Warner Losh 

Target specific values for vm parameters and details.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_vmparam.h  | 38 ++
 bsd-user/i386/target_arch_vmparam.h   | 46 +++
 bsd-user/qemu.h   |  1 +
 bsd-user/x86_64/target_arch_vmparam.h | 46 +++
 4 files changed, 131 insertions(+)
 create mode 100644 bsd-user/freebsd/target_os_vmparam.h
 create mode 100644 bsd-user/i386/target_arch_vmparam.h
 create mode 100644 bsd-user/x86_64/target_arch_vmparam.h

diff --git a/bsd-user/freebsd/target_os_vmparam.h 
b/bsd-user/freebsd/target_os_vmparam.h
new file mode 100644
index 00..990300c619
--- /dev/null
+++ b/bsd-user/freebsd/target_os_vmparam.h
@@ -0,0 +1,38 @@
+/*
+ *  FreeBSD VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_OS_VMPARAM_H_
+#define _TARGET_OS_VMPARAM_H_
+
+#include "target_arch_vmparam.h"
+
+/* Compare to sys/exec.h */
+struct target_ps_strings {
+abi_ulong ps_argvstr;
+uint32_t ps_nargvstr;
+abi_ulong ps_envstr;
+uint32_t ps_nenvstr;
+};
+
+extern abi_ulong target_stkbas;
+extern abi_ulong target_stksiz;
+
+#define TARGET_PS_STRINGS  ((target_stkbas + target_stksiz) - \
+sizeof(struct target_ps_strings))
+
+#endif /* !TARGET_OS_VMPARAM_H_ */
diff --git a/bsd-user/i386/target_arch_vmparam.h 
b/bsd-user/i386/target_arch_vmparam.h
new file mode 100644
index 00..bb7718265b
--- /dev/null
+++ b/bsd-user/i386/target_arch_vmparam.h
@@ -0,0 +1,46 @@
+/*
+ *  i386 VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to i386/include/vmparam.h */
+#define TARGET_MAXTSIZ  (128 * MiB) /* max text size */
+#define TARGET_DFLDSIZ  (128 * MiB) /* initial data size limit */
+#define TARGET_MAXDSIZ  (512 * MiB) /* max data size */
+#define TARGET_DFLSSIZ  (8 * MiB)   /* initial stack size limit */
+#define TARGET_MAXSSIZ  (64 * MiB)  /* max stack size */
+#define TARGET_SGROWSIZ (128 * KiB) /* amount to grow stack */
+
+#define TARGET_RESERVED_VA 0xf700
+
+#define TARGET_USRSTACK (0xbfc0)
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+return state->regs[R_ESP];
+}
+
+static inline void set_second_rval(CPUX86State *state, abi_ulong retval2)
+{
+state->regs[R_EDX] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index fea1a167e4..1b37757e06 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -41,6 +41,7 @@ extern enum BSDType bsd_type;
 #include "target_arch.h"
 #include "syscall_defs.h"
 #include "target_syscall.h"
+#include "target_os_vmparam.h"
 #include "exec/gdbstub.h"
 
 /*
diff --git a/bsd-user/x86_64/target_arch_vmparam.h 
b/bsd-user/x86_64/target_arch_vmparam.h
new file mode 100644
index 00..81a915f2e5
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_vmparam.h
@@ -0,0 +1,46 @@
+/*
+ *  Intel x86_64 VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; 

[PATCH v3 43/43] bsd-user: Update mapping to handle reserved and starting conditions

2021-09-02 Thread imp
From: Warner Losh 

Update the reserved base based on what platform we're on, as well as the
start of the mmap range. Update routines that find va ranges to interact
with the reserved ranges as well as properly align the mapping (this is
especially important for targets whose page size does not match the
host's). Loop where appropriate when the initial address space offered
by mmap does not meet the contraints.

This has 18e80c55bb6 from linux-user folded in to the upstream
bsd-user code as well.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/main.c |  43 -
 bsd-user/mmap.c | 415 
 bsd-user/qemu.h |   5 +-
 3 files changed, 392 insertions(+), 71 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 1602a02aba..8e18d0443c 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -52,12 +52,49 @@
 #include "target_arch_cpu.h"
 
 int singlestep;
-unsigned long mmap_min_addr;
 uintptr_t guest_base;
 static const char *cpu_model;
 static const char *cpu_type;
 bool have_guest_base;
+/*
+ * When running 32-on-64 we should make sure we can fit all of the possible
+ * guest address space into a contiguous chunk of virtual host memory.
+ *
+ * This way we will never overlap with our own libraries or binaries or stack
+ * or anything else that QEMU maps.
+ *
+ * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
+ * of the address for the kernel.  Some cpus rely on this and user space
+ * uses the high bit(s) for pointer tagging and the like.  For them, we
+ * must preserve the expected address space.
+ */
+#ifndef MAX_RESERVED_VA
+# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
+#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
+  (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
+/*
+ * There are a number of places where we assign reserved_va to a variable
+ * of type abi_ulong and expect it to fit.  Avoid the last page.
+ */
+#   define MAX_RESERVED_VA  (0xul & TARGET_PAGE_MASK)
+#  else
+#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
+#  endif
+# else
+#  define MAX_RESERVED_VA  0
+# endif
+#endif
+
+/*
+ * That said, reserving *too* much vm space via mmap can run into problems
+ * with rlimits, oom due to page table creation, etc.  We will still try it,
+ * if directed by the command-line option, but not by default.
+ */
+#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
+unsigned long reserved_va = MAX_RESERVED_VA;
+#else
 unsigned long reserved_va;
+#endif
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
@@ -439,6 +476,10 @@ int main(int argc, char **argv)
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
+if (reserved_va) {
+mmap_next_start = reserved_va;
+}
+
 {
 Error *err = NULL;
 if (seed_optarg != NULL) {
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 8918c4ae68..b40ab9045f 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -188,64 +188,207 @@ static int mmap_frag(abi_ulong real_start,
 return 0;
 }
 
-static abi_ulong mmap_next_start = 0x4000;
+#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
+# define TASK_UNMAPPED_BASE  (1ul << 38)
+#else
+# define TASK_UNMAPPED_BASE  0x4000
+#endif
+abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
-/* find a free memory area of size 'size'. The search starts at
-   'start'. If 'start' == 0, then a default start address is used.
-   Return -1 if error.
-*/
-/* page_init() marks pages used by the host as reserved to be sure not
-   to use them. */
-static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
+/*
+ * Subroutine of mmap_find_vma, used when we have pre-allocated a chunk of 
guest
+ * address space.
+ */
+static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
+abi_ulong alignment)
 {
-abi_ulong addr, addr1, addr_start;
+abi_ulong addr;
+abi_ulong end_addr;
 int prot;
-unsigned long new_brk;
+int looped = 0;
+
+if (size > reserved_va) {
+return (abi_ulong)-1;
+}
+
+size = HOST_PAGE_ALIGN(size) + alignment;
+end_addr = start + size;
+if (end_addr > reserved_va) {
+end_addr = reserved_va;
+}
+addr = end_addr - qemu_host_page_size;
 
-new_brk = (unsigned long)sbrk(0);
-if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) {
-/* This is a hack to catch the host allocating memory with brk().
-   If it uses mmap then we loose.
-   FIXME: We really want to avoid the host allocating memory in
-   the first place, and maybe leave some slack to avoid switching
-   to mmap.  */
-page_set_flags(last_brk & TARGET_PAGE_MASK,
-   TARGET_PAGE_ALIGN(new_brk),
-

[PATCH v3 38/43] bsd-user: elfload.c style catch up patch

2021-09-02 Thread imp
From: Warner Losh 

Various style fixes to elfload.c that were too painful to make earlier
in this series.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 208 ++---
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 05751f3ce7..3660961582 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -143,10 +143,12 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 exit(-1);
 }
 tmp1 = tmp;
-while (*tmp++);
+while (*tmp++) {
+continue;
+}
 len = tmp - tmp1;
 if (p < len) {  /* this shouldn't happen - 128kB */
-return 0;
+return 0;
 }
 while (len) {
 --p; --tmp; --len;
@@ -156,14 +158,14 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 if (!pag) {
 pag = g_try_malloc0(TARGET_PAGE_SIZE);
 page[p / TARGET_PAGE_SIZE] = pag;
-if (!pag)
+if (!pag) {
 return 0;
+}
 }
 }
 if (len == 0 || offset == 0) {
 *(pag + offset) = *tmp;
-}
-else {
+} else {
   int bytes_to_copy = (len > offset) ? offset : len;
   tmp -= bytes_to_copy;
   p -= bytes_to_copy;
@@ -182,16 +184,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, 
struct image_info *info,
 abi_ulong stack_base, size;
 abi_long addr;
 
-/* Create enough stack to hold everything.  If we don't use
- * it for args, we'll use it for something else...
+/*
+ * Create enough stack to hold everything.  If we don't use it for args,
+ * we'll use it for something else...
  */
 size = target_dflssiz;
 stack_base = TARGET_USRSTACK - size;
-addr = target_mmap(stack_base,
-size + qemu_host_page_size,
-PROT_READ | PROT_WRITE,
-MAP_PRIVATE | MAP_ANON,
--1, 0);
+addr = target_mmap(stack_base , size + qemu_host_page_size,
+PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 if (addr == -1) {
 perror("stk mmap");
 exit(-1);
@@ -210,55 +210,60 @@ static void setup_arg_pages(struct bsd_binprm *bprm, 
struct image_info *info,
 
 static void set_brk(abi_ulong start, abi_ulong end)
 {
-/* page-align the start and end addresses... */
-start = HOST_PAGE_ALIGN(start);
-end = HOST_PAGE_ALIGN(end);
-if (end <= start)
-return;
-if (target_mmap(start, end - start,
-   PROT_READ | PROT_WRITE | PROT_EXEC,
-   MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
-perror("cannot mmap brk");
-exit(-1);
-}
+/* page-align the start and end addresses... */
+start = HOST_PAGE_ALIGN(start);
+end = HOST_PAGE_ALIGN(end);
+if (end <= start) {
+return;
+}
+if (target_mmap(start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC,
+MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
+perror("cannot mmap brk");
+exit(-1);
+}
 }
 
 
-/* We need to explicitly zero any fractional pages after the data
-   section (i.e. bss).  This would contain the junk from the file that
-   should not be in memory. */
+/*
+ * We need to explicitly zero any fractional pages after the data
+ * section (i.e. bss).  This would contain the junk from the file that
+ * should not be in memory.
+ */
 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 {
-abi_ulong nbyte;
+abi_ulong nbyte;
 
-if (elf_bss >= last_bss)
-return;
+if (elf_bss >= last_bss) {
+return;
+}
 
-/* XXX: this is really a hack : if the real host page size is
-   smaller than the target page size, some pages after the end
-   of the file may not be mapped. A better fix would be to
-   patch target_mmap(), but it is more complicated as the file
-   size must be known */
-if (qemu_real_host_page_size < qemu_host_page_size) {
-abi_ulong end_addr, end_addr1;
-end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
-end_addr = HOST_PAGE_ALIGN(elf_bss);
-if (end_addr1 < end_addr) {
-mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-}
+/*
+ * XXX: this is really a hack : if the real host page size is
+ * smaller than the target page size, some pages after the end
+ * of the file may not be mapped. A better fix 

[PATCH v3 40/43] bsd-user: move qemu_log to later in the file

2021-09-02 Thread imp
From: Warner Losh 

Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/main.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 50c8fdc1e2..1de86ae493 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -71,14 +71,6 @@ unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial 
data size limit */
 unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
 unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
-void gemu_log(const char *fmt, ...)
-{
-va_list ap;
-
-va_start(ap, fmt);
-vfprintf(stderr, fmt, ap);
-va_end(ap);
-}
 
 void fork_start(void)
 {
@@ -167,6 +159,15 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+void gemu_log(const char *fmt, ...)
+{
+va_list ap;
+
+va_start(ap, fmt);
+vfprintf(stderr, fmt, ap);
+va_end(ap);
+}
+
 static void
 adjust_ssize(void)
 {
-- 
2.32.0




[PATCH v3 23/43] bsd-user: define max args in terms of pages

2021-09-02 Thread imp
From: Warner Losh 

For 32-bit platforms, pass in up to 256k of args. For 64-bit, bump that
to 512k.

Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/qemu.h | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 55d71130bb..fea1a167e4 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "qemu/units.h"
 #include "exec/cpu_ldst.h"
 #include "exec/exec-all.h"
 
@@ -101,11 +102,17 @@ extern const char *qemu_uname_release;
 extern unsigned long mmap_min_addr;
 
 /*
- * MAX_ARG_PAGES defines the number of pages allocated for arguments
- * and envelope for the new program. 32 should suffice, this gives
- * a maximum env+arg of 128kB w/4KB pages!
+ * TARGET_ARG_MAX defines the number of bytes allocated for arguments
+ * and envelope for the new program. 256k should suffice for a reasonable
+ * maxiumum env+arg in 32-bit environments, bump it up to 512k for !ILP32
+ * platforms.
  */
-#define MAX_ARG_PAGES 32
+#if TARGET_ABI_BITS > 32
+#define TARGET_ARG_MAX (512 * KiB)
+#else
+#define TARGET_ARG_MAX (256 * KiB)
+#endif
+#define MAX_ARG_PAGES (TARGET_ARG_MAX / TARGET_PAGE_SIZE)
 
 /*
  * This structure is used to hold the arguments that are
-- 
2.32.0




[PATCH v3 41/43] bsd-user: Implement interlock for atomic operations

2021-09-02 Thread imp
From: Warner Losh 

Implement the internlock in fork_start() and fork_end() to properly cope
with atomic operations and to safely keep state for parent and child
processes.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 1de86ae493..88244eb8fe 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -71,15 +71,39 @@ unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial 
data size limit */
 unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
 unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
+/* Helper routines for implementing atomic operations. */
 
 void fork_start(void)
 {
+start_exclusive();
+cpu_list_lock();
+mmap_fork_start();
 }
 
 void fork_end(int child)
 {
 if (child) {
+CPUState *cpu, *next_cpu;
+/*
+ * Child processes created by fork() only have a single thread.  
Discard
+ * information about the parent threads.
+ */
+CPU_FOREACH_SAFE(cpu, next_cpu) {
+if (cpu != thread_cpu) {
+QTAILQ_REMOVE_RCU(, cpu, node);
+}
+}
+mmap_fork_end(child);
+/*
+ * qemu_init_cpu_list() takes care of reinitializing the exclusive
+ * state, so we don't need to end_exclusive() here.
+ */
+qemu_init_cpu_list();
 gdbserver_fork(thread_cpu);
+} else {
+mmap_fork_end(child);
+cpu_list_unlock();
+end_exclusive();
 }
 }
 
-- 
2.32.0




[PATCH v3 34/43] bsd-user: update debugging in mmap.c

2021-09-02 Thread imp
From: Warner Losh 

Update the debugging code for new features and different targets.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Sean Bruno 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/mmap.c | 55 ++---
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 03119b1f20..8918c4ae68 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -68,8 +68,8 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
 int prot1, ret;
 
 #ifdef DEBUG_MMAP
-printf("mprotect: start=0x" TARGET_FMT_lx
-   " len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
+printf("mprotect: start=0x" TARGET_ABI_FMT_lx
+   "len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
@@ -250,28 +250,47 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 mmap_lock();
 #ifdef DEBUG_MMAP
 {
-printf("mmap: start=0x" TARGET_FMT_lx
-   " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
+printf("mmap: start=0x" TARGET_ABI_FMT_lx
+   " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=",
start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
-if (flags & MAP_FIXED)
+if (flags & MAP_ALIGNMENT_MASK) {
+printf("MAP_ALIGNED(%u) ", (flags & MAP_ALIGNMENT_MASK)
+>> MAP_ALIGNMENT_SHIFT);
+}
+#if MAP_GUARD
+if (flags & MAP_GUARD) {
+printf("MAP_GUARD ");
+}
+#endif
+if (flags & MAP_FIXED) {
 printf("MAP_FIXED ");
-if (flags & MAP_ANON)
+}
+if (flags & MAP_ANONYMOUS) {
 printf("MAP_ANON ");
-switch (flags & TARGET_BSD_MAP_FLAGMASK) {
-case MAP_PRIVATE:
+}
+#ifdef MAP_EXCL
+if (flags & MAP_EXCL) {
+printf("MAP_EXCL ");
+}
+#endif
+if (flags & MAP_PRIVATE) {
 printf("MAP_PRIVATE ");
-break;
-case MAP_SHARED:
+}
+if (flags & MAP_SHARED) {
 printf("MAP_SHARED ");
-break;
-default:
-printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK);
-break;
 }
-printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset);
+if (flags & MAP_NOCORE) {
+printf("MAP_NOCORE ");
+}
+#ifdef MAP_STACK
+if (flags & MAP_STACK) {
+printf("MAP_STACK ");
+}
+#endif
+printf("fd=%d offset=0x%llx\n", fd, offset);
 }
 #endif
 
@@ -399,7 +418,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 page_set_flags(start, start + len, prot | PAGE_VALID);
  the_end:
 #ifdef DEBUG_MMAP
-printf("ret=0x" TARGET_FMT_lx "\n", start);
+printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);
 page_dump(stdout);
 printf("\n");
 #endif
@@ -416,7 +435,9 @@ int target_munmap(abi_ulong start, abi_ulong len)
 int prot, ret;
 
 #ifdef DEBUG_MMAP
-printf("munmap: start=0x%lx len=0x%lx\n", start, len);
+printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x"
+   TARGET_ABI_FMT_lx "\n",
+   start, len);
 #endif
 if (start & ~TARGET_PAGE_MASK)
 return -EINVAL;
-- 
2.32.0




[PATCH v3 37/43] bsd-user: add stubbed out core dump support

2021-09-02 Thread imp
From: Warner Losh 

Add a stubbed-out version of the bsd-user fork's core dump support. This
allows elfload.c to be almost the same between what's upstream and
what's in qemu-project upstream w/o the burden of reviewing the core
dump support.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfcore.c | 10 ++
 bsd-user/elfload.c | 22 --
 bsd-user/qemu.h|  6 ++
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 bsd-user/elfcore.c

diff --git a/bsd-user/elfcore.c b/bsd-user/elfcore.c
new file mode 100644
index 00..c49d9280e2
--- /dev/null
+++ b/bsd-user/elfcore.c
@@ -0,0 +1,10 @@
+/* Stubbed out version of core dump support, explicitly in public domain */
+
+static int elf_core_dump(int signr, CPUArchState *env)
+{
+struct elf_note en = { 0 };
+
+bswap_note();
+
+return 0;
+}
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 11ca813c7a..05751f3ce7 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -26,15 +26,17 @@
 static abi_ulong target_auxents;   /* Where the AUX entries are in target */
 static size_t target_auxents_sz;   /* Size of AUX entries including AT_NULL */
 
+#include "target_arch_reg.h"
 #include "target_os_elf.h"
 #include "target_os_stack.h"
 #include "target_os_thread.h"
-
-#include "elf.h"
+#include "target_os_user.h"
 
 abi_ulong target_stksiz;
 abi_ulong target_stkbas;
 
+static int elf_core_dump(int signr, CPUArchState *env);
+
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
 memcpy(to, from, n);
@@ -100,15 +102,25 @@ static void bswap_sym(struct elf_sym *sym)
 bswap16s(>st_shndx);
 }
 
+static void bswap_note(struct elf_note *en)
+{
+bswap32s(>n_namesz);
+bswap32s(>n_descsz);
+bswap32s(>n_type);
+}
+
 #else /* ! BSWAP_NEEDED */
 
 static void bswap_ehdr(struct elfhdr *ehdr) { }
 static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
 static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
 static void bswap_sym(struct elf_sym *sym) { }
+static void bswap_note(struct elf_note *en) { }
 
 #endif /* ! BSWAP_NEEDED */
 
+#include "elfcore.c"
+
 /*
  * 'copy_elf_strings()' copies argument/envelope strings from user
  * memory to free pages in kernel mem. These are in a format ready
@@ -834,6 +846,12 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 info->entry = elf_entry;
 
+#ifdef USE_ELF_CORE_DUMP
+bprm->core_dump = _core_dump;
+#else
+bprm->core_dump = NULL;
+#endif
+
 return 0;
 }
 
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 3685156123..8d20554688 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -51,6 +51,7 @@ extern enum BSDType bsd_type;
  * kernel
  */
 struct image_info {
+abi_ulong load_bias;
 abi_ulong load_addr;
 abi_ulong start_code;
 abi_ulong end_code;
@@ -65,6 +66,9 @@ struct image_info {
 abi_ulong entry;
 abi_ulong code_offset;
 abi_ulong data_offset;
+abi_ulong arg_start;
+abi_ulong arg_end;
+uint32_t  elf_flags;
 };
 
 #define MAX_SIGQUEUE_SIZE 1024
@@ -132,6 +136,7 @@ struct bsd_binprm {
 char **envp;
 char *filename; /* (Given) Name of binary */
 char *fullpath; /* Full path of binary */
+int (*core_dump)(int, CPUArchState *);
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
@@ -145,6 +150,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 struct image_info *info);
 int load_flt_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 struct image_info *info);
+int is_target_elf_binary(int fd);
 
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
   unsigned long len);
-- 
2.32.0




[PATCH v3 19/43] bsd-user: start to move target CPU functions to target_arch*

2021-09-02 Thread imp
From: Warner Losh 

Move the CPU functions into target_arch_cpu.c that are unique to each
CPU. These are defined in target_arch.h.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/target_arch.h   | 31 +
 bsd-user/i386/target_arch_cpu.c   | 75 +++
 bsd-user/main.c   | 35 ---
 bsd-user/x86_64/target_arch.h | 31 +
 bsd-user/x86_64/target_arch_cpu.c | 75 +++
 configure |  7 +--
 meson.build   |  7 ++-
 7 files changed, 218 insertions(+), 43 deletions(-)
 create mode 100644 bsd-user/i386/target_arch.h
 create mode 100644 bsd-user/i386/target_arch_cpu.c
 create mode 100644 bsd-user/x86_64/target_arch.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.c

diff --git a/bsd-user/i386/target_arch.h b/bsd-user/i386/target_arch.h
new file mode 100644
index 00..73e9a028fe
--- /dev/null
+++ b/bsd-user/i386/target_arch.h
@@ -0,0 +1,31 @@
+/*
+ * Intel x86 specific prototypes for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+/* target_arch_cpu.c */
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+int flags);
+void bsd_i386_set_idt(int n, unsigned int dpl);
+void bsd_i386_set_idt_base(uint64_t base);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* ! _TARGET_ARCH_H_ */
diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
new file mode 100644
index 00..7f2f755a11
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -0,0 +1,75 @@
+/*
+ *  i386 cpu related code
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#include 
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu.h"
+#include "qemu/timer.h"
+
+#include "target_arch.h"
+
+static uint64_t *idt_table;
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+return cpu_get_host_ticks();
+}
+
+int cpu_get_pic_interrupt(CPUX86State *env)
+{
+return -1;
+}
+
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+ int flags)
+{
+unsigned int e1, e2;
+uint32_t *p;
+e1 = (addr << 16) | (limit & 0x);
+e2 = ((addr >> 16) & 0xff) | (addr & 0xff00) | (limit & 0x000f);
+e2 |= flags;
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+ uint32_t addr, unsigned int sel)
+{
+uint32_t *p, e1, e2;
+e1 = (addr & 0x) | (sel << 16);
+e2 = (addr & 0x) | 0x8000 | (dpl << 13) | (type << 8);
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+/* only dpl matters as we do only user space emulation */
+void bsd_i386_set_idt(int n, unsigned int dpl)
+{
+set_gate(idt_table + n, 0, dpl, 0, 0);
+}
+
+void bsd_i386_set_idt_base(uint64_t base)
+{
+idt_table = g2h_untagged(base);
+}
+
diff --git a/bsd-user/main.c b/bsd-user/main.c
index d7c8a3e348..f7c75df64d 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -72,13 +72,6 @@ void gemu_log(const char *fmt, ...)
 va_end(ap);
 }
 
-#if defined(TARGET_I386)
-int cpu_get_pic_interrupt(CPUX86State *env)
-{
-return -1;
-}
-#endif
-
 void fork_start(void)
 {
 }
@@ -94,11 +87,6 @@ void fork_end(int child)
 /***/
 /* CPUX86 core interface */
 
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
-return cpu_get_host_ticks();
-}
-
 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
   

[PATCH v3 30/43] bsd-user: elf cleanup

2021-09-02 Thread imp
From: Warner Losh 

Move OS-dependent defines into target_os_elf.h. Move the architectural
dependent stuff into target_arch_elf.h. Adjust elfload.c to use
target_create_elf_tables instead of create_elf_tables.

Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Justin Hibbits 
Signed-off-by: Alexander Kabaev 
Acked-by: Richard Henderson 
---
 bsd-user/elfload.c   | 191 ---
 bsd-user/freebsd/target_os_elf.h | 137 ++
 bsd-user/netbsd/target_os_elf.h  | 146 +++
 bsd-user/openbsd/target_os_elf.h | 146 +++
 bsd-user/qemu.h  |   1 +
 5 files changed, 454 insertions(+), 167 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_elf.h
 create mode 100644 bsd-user/netbsd/target_os_elf.h
 create mode 100644 bsd-user/openbsd/target_os_elf.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 59465b71d4..6156f9775d 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,48 +23,17 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
-#include "target_arch_elf.h"
-#include "target_os_thread.h"
-
-/* this flag is uneffective under linux too, should be deleted */
-#ifndef MAP_DENYWRITE
-#define MAP_DENYWRITE 0
-#endif
-
-/* should probably go in elf.h */
-#ifndef ELIBBAD
-#define ELIBBAD 80
-#endif
-
-#ifndef ELF_PLATFORM
-#define ELF_PLATFORM (NULL)
-#endif
-
-#ifndef ELF_HWCAP
-#define ELF_HWCAP 0
-#endif
+static abi_ulong target_auxents;   /* Where the AUX entries are in target */
+static size_t target_auxents_sz;   /* Size of AUX entries including AT_NULL */
 
-#ifdef TARGET_ABI32
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
-#undef bswaptls
-#define bswaptls(ptr) bswap32s(ptr)
-#endif
+#include "target_os_elf.h"
+#include "target_os_stack.h"
+#include "target_os_thread.h"
 
 #include "elf.h"
 
-/* max code+data+bss space allocated to elf interpreter */
-#define INTERP_MAP_SIZE (32 * 1024 * 1024)
-
-/* max code+data+bss+brk space allocated to ET_DYN executables */
-#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
-
-/* Necessary parameters */
-#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
-#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned 
long)(TARGET_ELF_EXEC_PAGESIZE - 1))
-#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
-
-#define DLINFO_ITEMS 12
+abi_ulong target_stksiz;
+abi_ulong target_stkbas;
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
@@ -195,43 +164,36 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 return p;
 }
 
-static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
- struct image_info *info)
+static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
+abi_ulong *stackp, abi_ulong *stringp)
 {
-abi_ulong stack_base, size, error;
-int i;
+abi_ulong stack_base, size;
+abi_long addr;
 
 /* Create enough stack to hold everything.  If we don't use
  * it for args, we'll use it for something else...
  */
 size = target_dflssiz;
-if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE)
-size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
-error = target_mmap(0,
+stack_base = TARGET_USRSTACK - size;
+addr = target_mmap(stack_base,
 size + qemu_host_page_size,
 PROT_READ | PROT_WRITE,
 MAP_PRIVATE | MAP_ANON,
 -1, 0);
-if (error == -1) {
+if (addr == -1) {
 perror("stk mmap");
 exit(-1);
 }
 /* we reserve one extra page at the top of the stack as guard */
-target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
+target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
 
-stack_base = error + size - MAX_ARG_PAGES * TARGET_PAGE_SIZE;
-p += stack_base;
+target_stksiz = size;
+target_stkbas = addr;
 
-for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-if (bprm->page[i]) {
-info->rss++;
-/* FIXME - check return value of memcpy_to_target() for failure */
-memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
-g_free(bprm->page[i]);
-}
-stack_base += TARGET_PAGE_SIZE;
+if (setup_initial_stack(bprm, stackp, stringp) != 0) {
+perror("stk setup");
+exit(-1);
 }
-return p;
 }
 
 static void set_brk(abi_ulong start, abi_ulong end)
@@ -287,86 +249,6 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 }
 }
 
-
-static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
-   struct elfhdr * exec,
-   abi_ulong load_addr,
-   abi_ulong load_bias,
-   abi_ulong interp_load_addr,
-  

[PATCH v3 21/43] bsd-user: pull in target_arch_thread.h update target_arch_elf.h

2021-09-02 Thread imp
From: Warner Losh 

Update target_arch_elf.h to remove thread_init. Move its contents to
target_arch_thread.h and rename to target_thread_init(). Update
elfload.c to call it. Create thread_os_thread.h to hold the os specific
parts of the thread and threat manipulation routines. Currently, it just
includes target_arch_thread.h. target_arch_thread.h contains the at the
moment unused target_thread_set_upcall which will be used in the future
when creating actual thread (i386 has this stubbed, but other
architectures in the bsd-user tree have real ones). FreeBSD doesn't do
AT_HWCAP, so remove that code. Linux does, and this code came from there.

These changes are all interrelated and could be brokend own, but seem to
represent a reviewable changeset since most of the change is boiler
plate.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c   |  4 ++-
 bsd-user/freebsd/target_os_thread.h  | 25 +
 bsd-user/i386/target_arch_elf.h  | 52 ++--
 bsd-user/i386/target_arch_thread.h   | 47 +
 bsd-user/netbsd/target_os_thread.h   | 25 +
 bsd-user/openbsd/target_os_thread.h  | 25 +
 bsd-user/x86_64/target_arch_elf.h| 38 ++--
 bsd-user/x86_64/target_arch_thread.h | 40 +
 8 files changed, 171 insertions(+), 85 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_thread.h
 create mode 100644 bsd-user/i386/target_arch_thread.h
 create mode 100644 bsd-user/netbsd/target_os_thread.h
 create mode 100644 bsd-user/openbsd/target_os_thread.h
 create mode 100644 bsd-user/x86_64/target_arch_thread.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index ccb1744800..c28ef34143 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -24,6 +24,7 @@
 #include "qemu/path.h"
 
 #include "target_arch_elf.h"
+#include "target_os_thread.h"
 
 /* this flag is uneffective under linux too, should be deleted */
 #ifndef MAP_DENYWRITE
@@ -1001,5 +1002,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
-init_thread(regs, infop);
+
+target_thread_init(regs, infop);
 }
diff --git a/bsd-user/freebsd/target_os_thread.h 
b/bsd-user/freebsd/target_os_thread.h
new file mode 100644
index 00..77433acdff
--- /dev/null
+++ b/bsd-user/freebsd/target_os_thread.h
@@ -0,0 +1,25 @@
+/*
+ *  FreeBSD thread dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_THREAD_H_
+#define _TARGET_OS_THREAD_H_
+
+#include "target_arch_thread.h"
+
+#endif /* !_TARGET_OS_THREAD_H_ */
diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
index 84f61bd930..eb760e07fa 100644
--- a/bsd-user/i386/target_arch_elf.h
+++ b/bsd-user/i386/target_arch_elf.h
@@ -19,62 +19,16 @@
 #ifndef _TARGET_ARCH_ELF_H_
 #define _TARGET_ARCH_ELF_H_
 
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
-static char elf_platform[] = "i386";
-int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6) {
-family = 6;
-}
-if (family >= 3) {
-elf_platform[1] = '0' + family;
-}
-return elf_platform;
-}
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
-X86CPU *cpu = X86_CPU(thread_cpu);
-
-return cpu->env.features[FEAT_1_EDX];
-}
-
 #define ELF_START_MMAP 0x8000
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
+#define ELF_ET_DYN_LOAD_ADDR0x01001000
 #define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
 
-/*
- * These are used to set parameters in the core dumps.
- */
+#define ELF_HWCAP   0 /* FreeBSD doesn't do AT_HWCAP{,2} on x86 */
+
 #define ELF_CLASS   ELFCLASS32
 #define ELF_DATAELFDATA2LSB
 #define ELF_ARCHEM_386
 
-static inline void init_thread(struct target_pt_regs *regs,
-   struct image_info *infop)
-{
-regs->esp = infop->start_stack;
-regs->eip = infop->entry;
-
-/*
- * SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
- * starts %edx contains a pointer to a function which 

[PATCH v3 36/43] bsd-user: Add target_os_user.h to capture the user/kernel structures

2021-09-02 Thread imp
From: Warner Losh 

This file evolved over the years to capture the user/kernel interfaces,
including those that changed over time.

Signed-off-by: Stacey Son 
Signed-off-by: Michal Meloun 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_user.h | 427 ++
 1 file changed, 427 insertions(+)
 create mode 100644 bsd-user/freebsd/target_os_user.h

diff --git a/bsd-user/freebsd/target_os_user.h 
b/bsd-user/freebsd/target_os_user.h
new file mode 100644
index 00..95b1fa9f99
--- /dev/null
+++ b/bsd-user/freebsd/target_os_user.h
@@ -0,0 +1,427 @@
+/*
+ *  sys/user.h definitions
+ *
+ *  Copyright (c) 2015 Stacey D. Son (sson at FreeBSD)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_USER_H_
+#define _TARGET_OS_USER_H_
+
+/*
+ * from sys/priority.h
+ */
+struct target_priority {
+uint8_t pri_class;  /* Scheduling class. */
+uint8_t pri_level;  /* Normal priority level. */
+uint8_t pri_native; /* Priority before propogation. */
+uint8_t pri_user;   /* User priority based on p_cpu and p_nice. */
+};
+
+/*
+ * sys/caprights.h
+ */
+#define TARGET_CAP_RIGHTS_VERSION  0
+
+typedef struct target_cap_rights {
+uint64_tcr_rights[TARGET_CAP_RIGHTS_VERSION + 2];
+} target_cap_rights_t;
+
+/*
+ * From sys/_socketaddr_storage.h
+ *
+ */
+#define TARGET_SS_MAXSIZE 128U
+#define TARGET_SS_ALIGNSIZE   (sizeof(__int64_t))
+#define TARGET_SS_PAD1SIZE(TARGET_SS_ALIGNSIZE - sizeof(unsigned char) - \
+sizeof(uint8_t))
+#define TARGET_SS_PAD2SIZE(TARGET_SS_MAXSIZE - sizeof(unsigned char) - \
+sizeof(uint8_t) - TARGET_SS_PAD1SIZE - TARGET_SS_ALIGNSIZE)
+
+struct target_sockaddr_storage {
+unsigned char   ss_len; /* address length */
+uint8_t ss_family;  /* address family */
+char__ss_pad1[TARGET_SS_PAD1SIZE];
+__int64_t   __ss_align; /* force desired struct alignment */
+char__ss_pad2[TARGET_SS_PAD2SIZE];
+};
+
+/*
+ * from sys/user.h
+ */
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031
+#define TARGET_KI_NSPARE_INT2
+#elif defined(__FreeBSD_version) && __FreeBSD_version >= 110
+#define TARGET_KI_NSPARE_INT4
+#elif defined(__FreeBSD_version) && __FreeBSD_version >= 100
+#define TARGET_KI_NSPARE_INT7
+#else
+#define TARGET_KI_NSPARE_INT9
+#endif /* ! __FreeBSD_version >= 100 */
+#define TARGET_KI_NSPARE_LONG   12
+#define TARGET_KI_NSPARE_PTR6
+
+#define TARGET_WMESGLEN 8
+#define TARGET_LOCKNAMELEN  8
+#define TARGET_TDNAMLEN 16
+#define TARGET_COMMLEN  19
+#define TARGET_KI_EMULNAMELEN   16
+#define TARGET_KI_NGROUPS   16
+#define TARGET_LOGNAMELEN   17
+#define TARGET_LOGINCLASSLEN17
+
+#define TARGET_KF_TYPE_NONE 0
+#define TARGET_KF_TYPE_VNODE1
+#define TARGET_KF_TYPE_SOCKET   2
+#define TARGET_KF_TYPE_PIPE 3
+#define TARGET_KF_TYPE_FIFO 4
+#define TARGET_KF_TYPE_KQUEUE   5
+#define TARGET_KF_TYPE_CRYPTO   6
+#define TARGET_KF_TYPE_MQUEUE   7
+#define TARGET_KF_TYPE_SHM  8
+#define TARGET_KF_TYPE_SEM  9
+#define TARGET_KF_TYPE_PTS  10
+#define TARGET_KF_TYPE_PROCDESC 11
+#define TARGET_KF_TYPE_DEV  12
+#define TARGET_KF_TYPE_UNKNOWN  255
+
+struct target_kinfo_proc {
+int32_t ki_structsize;  /* size of this structure */
+int32_t ki_layout;  /* reserved: layout identifier */
+abi_ulong   ki_args;/* address of command arguments */
+abi_ulong   ki_paddr;   /* address of proc */
+abi_ulong   ki_addr;/* kernel virtual addr of u-area */
+abi_ulong   ki_tracep;  /* pointer to trace file */
+abi_ulong   ki_textvp;  /* pointer to executable file */
+abi_ulong   ki_fd;  /* pointer to open file info */
+abi_ulong   ki_vmspace; /* pointer to kernel vmspace struct */
+abi_ulong   ki_wchan;   /* sleep address */
+int32_t ki_pid; /* Process identifier */
+int32_t ki_ppid;/* parent process id */
+int32_t ki_pgid;/* process group id */
+int32_t ki_tpgid;

[PATCH v3 18/43] bsd-user: save the path to the qemu emulator

2021-09-02 Thread imp
From: Warner Losh 

Save the path to the qemu emulator. This will be used later when we have
a more complete implementation of exec.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/main.c | 21 +
 bsd-user/qemu.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 607fdd8380..d7c8a3e348 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -43,6 +43,8 @@
 
 #include "host-os.h"
 
+#include 
+
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -52,6 +54,7 @@ unsigned long reserved_va;
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
 enum BSDType bsd_type;
+char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */
 
 /*
  * XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
@@ -336,6 +339,22 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+static void save_proc_pathname(char *argv0)
+{
+int mib[4];
+size_t len;
+
+mib[0] = CTL_KERN;
+mib[1] = KERN_PROC;
+mib[2] = KERN_PROC_PATHNAME;
+mib[3] = -1;
+
+len = sizeof(qemu_proc_pathname);
+if (sysctl(mib, 4, qemu_proc_pathname, , NULL, 0)) {
+perror("sysctl");
+}
+}
+
 int main(int argc, char **argv)
 {
 const char *filename;
@@ -360,6 +379,8 @@ int main(int argc, char **argv)
 usage();
 }
 
+save_proc_pathname(argv[0]);
+
 error_init(argv[0]);
 module_call_init(MODULE_INIT_TRACE);
 qemu_init_cpu_list();
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index cf248ad3df..6c4ec61d76 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -207,6 +207,7 @@ void mmap_fork_start(void);
 void mmap_fork_end(int child);
 
 /* main.c */
+extern char qemu_proc_pathname[];
 extern unsigned long x86_stack_size;
 
 /* user access */
-- 
2.32.0




[PATCH v3 32/43] bsd-user: Rewrite target system call definintion glue

2021-09-02 Thread imp
From: Warner Losh 

Rewrite target definnitions to interface with the FreeBSD system calls.
This covers basic types (time_t, iovec, umtx_time, timespec, timeval,
rusage, rwusage) and basic defines (mmap, rusage). Also included are
FreeBSD version-specific variations.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-mman.h | 121 
 bsd-user/mmap.c |   2 -
 bsd-user/syscall_defs.h | 247 ++--
 3 files changed, 162 insertions(+), 208 deletions(-)
 delete mode 100644 bsd-user/bsd-mman.h

diff --git a/bsd-user/bsd-mman.h b/bsd-user/bsd-mman.h
deleted file mode 100644
index 910e8c1921..00
--- a/bsd-user/bsd-mman.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1993
- *  The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *may be used to endorse or promote products derived from this software
- *without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *  @(#)mman.h  8.2 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/sys/mman.h,v 1.42 2008/03/28 04:29:27 ps Exp $
- */
-
-#define TARGET_FREEBSD_MAP_RESERVED0080 0x0080  /* previously misimplemented 
MAP_INHERIT */
-#define TARGET_FREEBSD_MAP_RESERVED0100 0x0100  /* previously unimplemented 
MAP_NOEXTEND */
-#define TARGET_FREEBSD_MAP_STACK0x0400  /* region grows down, like a 
stack */
-#define TARGET_FREEBSD_MAP_NOSYNC   0x0800  /* page to but do not sync 
underlying file */
-
-#define TARGET_FREEBSD_MAP_FLAGMASK 0x1ff7
-
-/*  $NetBSD: mman.h,v 1.42 2008/11/18 22:13:49 ad Exp $ */
-
-/*-
- * Copyright (c) 1982, 1986, 1993
- *  The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *may be used to endorse or promote products derived from this software
- *without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *  @(#)mman.h  8.2 (Berkeley) 1/9/95
- */
-#define TARGET_NETBSD_MAP_INHERIT   0x0080  /* region is retained after 
exec */
-#define TARGET_NETBSD_MAP_TRYFIXED  0x0400 /* attempt hint address, even 
within break */
-#define TARGET_NETBSD_MAP_WIRED 0x0800  /* mlock() mapping when it is 
established */
-
-#define TARGET_NETBSD_MAP_STACK   

[PATCH v3 27/43] bsd-user: Implement --seed and initialize random state

2021-09-02 Thread imp
From: Warner Losh 

Copy --seed implementation (translated from linux-user's newer command
line scheme to the older one bsd-user still uses). Initialize the
randomness with the glibc if a specific seed is specified or use the
qcrypto library if not.

Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 19bf3a09a7..71fd9d5aba 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -45,6 +45,8 @@
 #include "qemu/cutils.h"
 #include "exec/log.h"
 #include "trace/control.h"
+#include "crypto/init.h"
+#include "qemu/guest-random.h"
 
 #include "host-os.h"
 #include "target_arch_cpu.h"
@@ -203,6 +205,7 @@ int main(int argc, char **argv)
 const char *cpu_type;
 const char *log_file = NULL;
 const char *log_mask = NULL;
+const char *seed_optarg = NULL;
 struct target_pt_regs regs1, *regs = 
 struct image_info info1, *info = 
 struct bsd_binprm bprm;
@@ -331,6 +334,8 @@ int main(int argc, char **argv)
 usage();
 }
 optind++;
+} else if (!strcmp(r, "seed")) {
+seed_optarg = optarg;
 } else if (!strcmp(r, "singlestep")) {
 singlestep = 1;
 } else if (!strcmp(r, "strace")) {
@@ -403,6 +408,19 @@ int main(int argc, char **argv)
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
+{
+Error *err = NULL;
+if (seed_optarg != NULL) {
+qemu_guest_random_seed_main(seed_optarg, );
+} else {
+qcrypto_init();
+}
+if (err) {
+error_reportf_err(err, "cannot initialize crypto: ");
+exit(1);
+}
+}
+
 /*
  * Now that page sizes are configured we can do
  * proper page alignment for guest_base.
-- 
2.32.0




[PATCH v3 25/43] bsd-user: Add system independent stack, data and text limiting

2021-09-02 Thread imp
From: Warner Losh 

Eliminate the x86 specific stack stuff in favor of more generic control
over the process size:
target_maxtsiz  max text size
target_dfldsiz  initial data size limit
target_maxdsiz  max data size
target_dflssiz  initial stack size limit
target_maxssiz  max stack size
target_sgrowsiz amount to grow stack
These can be set on a per-arch basis, and the stack size can be set
on the command line. Adjust the stack size parameters at startup.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c |  2 +-
 bsd-user/main.c| 52 +-
 bsd-user/qemu.h|  7 ++-
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index c28ef34143..59465b71d4 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -204,7 +204,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct 
bsd_binprm *bprm,
 /* Create enough stack to hold everything.  If we don't use
  * it for args, we'll use it for something else...
  */
-size = x86_stack_size;
+size = target_dflssiz;
 if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE)
 size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
 error = target_mmap(0,
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 3d4ed202a0..19bf3a09a7 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -18,6 +18,11 @@
  *  along with this program; if not, see .
  */
 
+#include 
+#include 
+#include 
+#include 
+
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/units.h"
@@ -44,8 +49,6 @@
 #include "host-os.h"
 #include "target_arch_cpu.h"
 
-#include 
-
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -57,12 +60,12 @@ const char *qemu_uname_release;
 enum BSDType bsd_type;
 char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */
 
-/*
- * XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
- * we allocate a bigger stack. Need a better solution, for example
- * by remapping the process stack directly at the right place
- */
-unsigned long x86_stack_size = 512 * 1024;
+unsigned long target_maxtsiz = TARGET_MAXTSIZ;   /* max text size */
+unsigned long target_dfldsiz = TARGET_DFLDSIZ;   /* initial data size limit */
+unsigned long target_maxdsiz = TARGET_MAXDSIZ;   /* max data size */
+unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial data size limit */
+unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
+unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
 void gemu_log(const char *fmt, ...)
 {
@@ -112,7 +115,6 @@ static void usage(void)
"-d item1[,...]enable logging of specified items\n"
"  (use '-d help' for a list of log items)\n"
"-D logfilewrite logs to 'logfile' (default stderr)\n"
-   "-p pagesize   set the host page size to 'pagesize'\n"
"-singlestep   always run in singlestep mode\n"
"-strace   log system calls\n"
"-trace
[[enable=]][,events=][,file=]\n"
@@ -132,7 +134,7 @@ static void usage(void)
,
TARGET_NAME,
interp_prefix,
-   x86_stack_size);
+   target_dflssiz);
 exit(1);
 }
 
@@ -161,6 +163,23 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+static void
+adjust_ssize(void)
+{
+struct rlimit rl;
+
+if (getrlimit(RLIMIT_STACK, ) != 0) {
+return;
+}
+
+target_maxssiz = MIN(target_maxssiz, rl.rlim_max);
+target_dflssiz = MIN(MAX(target_dflssiz, rl.rlim_cur), target_maxssiz);
+
+rl.rlim_max = target_maxssiz;
+rl.rlim_cur = target_dflssiz;
+setrlimit(RLIMIT_STACK, );
+}
+
 static void save_proc_pathname(char *argv0)
 {
 int mib[4];
@@ -197,6 +216,8 @@ int main(int argc, char **argv)
 envlist_t *envlist = NULL;
 bsd_type = HOST_DEFAULT_BSD_TYPE;
 
+adjust_ssize();
+
 if (argc <= 1) {
 usage();
 }
@@ -257,14 +278,17 @@ int main(int argc, char **argv)
 }
 } else if (!strcmp(r, "s")) {
 r = argv[optind++];
-rv = qemu_strtoul(r, , 0, _stack_size);
-if (rv < 0 || x86_stack_size <= 0) {
+rv = qemu_strtoul(r, , 0, _dflssiz);
+if (rv < 0 || target_dflssiz <= 0) {
 usage();
 }
 if (*r == 'M') {
-x86_stack_size *= MiB;
+target_dflssiz *= 1024 * 1024;
 } else if (*r == 'k' || *r == 'K') {
-x86_stack_size *= KiB;
+target_dflssiz *= 1024;
+}
+if (target_dflssiz > target_maxssiz) {
+usage();
 }
 } else if (!strcmp(r, "L")) {
 interp_prefix = argv[optind++];
diff --git a/bsd-user/qemu.h 

[PATCH v3 22/43] bsd-user: Include more things in qemu.h

2021-09-02 Thread imp
From: Warner Losh 

Include more header files to match bsd-user fork.

Signed-off-by: Warner Losh 
---
 bsd-user/qemu.h | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5e4cbb40d4..55d71130bb 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -18,12 +18,12 @@
 #define QEMU_H
 
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
 
 #undef DEBUG_REMAP
-#ifdef DEBUG_REMAP
-#endif /* DEBUG_REMAP */
 
 #include "exec/user/abitypes.h"
 
@@ -36,6 +36,8 @@ enum BSDType {
 };
 extern enum BSDType bsd_type;
 
+#include "exec/user/thunk.h"
+#include "target_arch.h"
 #include "syscall_defs.h"
 #include "target_syscall.h"
 #include "exec/gdbstub.h"
-- 
2.32.0




[PATCH v3 15/43] bsd-user: assume pthreads and support of __thread

2021-09-02 Thread imp
From: Warner Losh 

All compilers for some time have supported this. Follow linux-user and
eliminate the #define THREAD and unconditionally insert __thread where
needed. Please insert: "(see 24cb36a61c6: "configure: Make NPTL
non-optional")"

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 bsd-user/main.c |  2 +-
 bsd-user/qemu.h | 10 +-
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 1388c7a13d..e06cc7b414 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -309,7 +309,7 @@ static void usage(void)
 exit(1);
 }
 
-THREAD CPUState *thread_cpu;
+__thread CPUState *thread_cpu;
 
 bool qemu_cpu_is_self(CPUState *cpu)
 {
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index d1ab58a8eb..cf248ad3df 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -40,12 +40,6 @@ extern enum BSDType bsd_type;
 #include "target_syscall.h"
 #include "exec/gdbstub.h"
 
-#if defined(CONFIG_USE_NPTL)
-#define THREAD __thread
-#else
-#define THREAD
-#endif
-
 /*
  * This struct is used to hold certain information about the image.  Basically,
  * it replicates in user space what would be certain task_struct fields in the
@@ -155,7 +149,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 abi_long arg2, abi_long arg3, abi_long arg4,
 abi_long arg5, abi_long arg6);
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-extern THREAD CPUState *thread_cpu;
+extern __thread CPUState *thread_cpu;
 void cpu_loop(CPUArchState *env);
 char *target_strerror(int err);
 int get_osversion(void);
@@ -422,8 +416,6 @@ static inline void *lock_user_string(abi_ulong guest_addr)
 #define unlock_user_struct(host_ptr, guest_addr, copy)  \
 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
 
-#if defined(CONFIG_USE_NPTL)
 #include 
-#endif
 
 #endif /* QEMU_H */
-- 
2.32.0




[PATCH v3 33/43] bsd-user: Make cpu_model and cpu_type visible to all of main.c

2021-09-02 Thread imp
From: Warner Losh 

cpu_model and cpu_type will be used future commits, so move them from
main() scoped to file scoped.

Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 71fd9d5aba..50c8fdc1e2 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -54,6 +54,8 @@
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
+static const char *cpu_model;
+static const char *cpu_type;
 bool have_guest_base;
 unsigned long reserved_va;
 
@@ -201,8 +203,6 @@ static void save_proc_pathname(char *argv0)
 int main(int argc, char **argv)
 {
 const char *filename;
-const char *cpu_model;
-const char *cpu_type;
 const char *log_file = NULL;
 const char *log_mask = NULL;
 const char *seed_optarg = NULL;
-- 
2.32.0




[PATCH v3 13/43] bsd-user: TARGET_NGROUPS unused in this file, remove

2021-09-02 Thread imp
From: Warner Losh 

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/bsdload.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 6aefc7a28b..5b3c061a45 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -19,8 +19,6 @@
 
 #include "qemu.h"
 
-#define TARGET_NGROUPS 32
-
 /* ??? This should really be somewhere else.  */
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
   unsigned long len)
-- 
2.32.0




[PATCH v3 14/43] bsd-user: elfload: simplify bswap a bit.

2021-09-02 Thread imp
From: Warner Losh 

Reduce the number of ifdefs by always calling the swapping routine, but
making them empty when swapping isn't needed.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 97 ++
 1 file changed, 47 insertions(+), 50 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 4f3fa83c2c..ccb1744800 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -67,13 +67,13 @@
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
-memcpy(to, from, n);
+memcpy(to, from, n);
 }
 
 #ifdef BSWAP_NEEDED
 static void bswap_ehdr(struct elfhdr *ehdr)
 {
-bswap16s(>e_type);/* Object file type */
+bswap16s(>e_type);/* Object file type */
 bswap16s(>e_machine); /* Architecture */
 bswap32s(>e_version); /* Object file version */
 bswaptls(>e_entry);   /* Entry point virtual address */
@@ -81,37 +81,45 @@ static void bswap_ehdr(struct elfhdr *ehdr)
 bswaptls(>e_shoff);   /* Section header table file offset */
 bswap32s(>e_flags);   /* Processor-specific flags */
 bswap16s(>e_ehsize);  /* ELF header size in bytes */
-bswap16s(>e_phentsize);   /* Program header table entry 
size */
+bswap16s(>e_phentsize);   /* Program header table entry size */
 bswap16s(>e_phnum);   /* Program header table entry count */
-bswap16s(>e_shentsize);   /* Section header table entry 
size */
+bswap16s(>e_shentsize);   /* Section header table entry size */
 bswap16s(>e_shnum);   /* Section header table entry count */
-bswap16s(>e_shstrndx);/* Section header string table 
index */
+bswap16s(>e_shstrndx);/* Section header string table index */
 }
 
-static void bswap_phdr(struct elf_phdr *phdr)
+static void bswap_phdr(struct elf_phdr *phdr, int phnum)
 {
-bswap32s(>p_type);/* Segment type */
-bswaptls(>p_offset);  /* Segment file offset */
-bswaptls(>p_vaddr);   /* Segment virtual address */
-bswaptls(>p_paddr);   /* Segment physical address */
-bswaptls(>p_filesz);  /* Segment size in file */
-bswaptls(>p_memsz);   /* Segment size in memory */
-bswap32s(>p_flags);   /* Segment flags */
-bswaptls(>p_align);   /* Segment alignment */
+int i;
+
+for (i = 0; i < phnum; i++, phdr++) {
+bswap32s(>p_type);/* Segment type */
+bswap32s(>p_flags);   /* Segment flags */
+bswaptls(>p_offset);  /* Segment file offset */
+bswaptls(>p_vaddr);   /* Segment virtual address */
+bswaptls(>p_paddr);   /* Segment physical address */
+bswaptls(>p_filesz);  /* Segment size in file */
+bswaptls(>p_memsz);   /* Segment size in memory */
+bswaptls(>p_align);   /* Segment alignment */
+}
 }
 
-static void bswap_shdr(struct elf_shdr *shdr)
+static void bswap_shdr(struct elf_shdr *shdr, int shnum)
 {
-bswap32s(>sh_name);
-bswap32s(>sh_type);
-bswaptls(>sh_flags);
-bswaptls(>sh_addr);
-bswaptls(>sh_offset);
-bswaptls(>sh_size);
-bswap32s(>sh_link);
-bswap32s(>sh_info);
-bswaptls(>sh_addralign);
-bswaptls(>sh_entsize);
+int i;
+
+for (i = 0; i < shnum; i++, shdr++) {
+bswap32s(>sh_name);
+bswap32s(>sh_type);
+bswaptls(>sh_flags);
+bswaptls(>sh_addr);
+bswaptls(>sh_offset);
+bswaptls(>sh_size);
+bswap32s(>sh_link);
+bswap32s(>sh_info);
+bswaptls(>sh_addralign);
+bswaptls(>sh_entsize);
+}
 }
 
 static void bswap_sym(struct elf_sym *sym)
@@ -121,7 +129,15 @@ static void bswap_sym(struct elf_sym *sym)
 bswaptls(>st_size);
 bswap16s(>st_shndx);
 }
-#endif
+
+#else /* ! BSWAP_NEEDED */
+
+static void bswap_ehdr(struct elfhdr *ehdr) { }
+static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
+static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
+static void bswap_sym(struct elf_sym *sym) { }
+
+#endif /* ! BSWAP_NEEDED */
 
 /*
  * 'copy_elf_strings()' copies argument/envelope strings from user
@@ -367,9 +383,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 last_bss = 0;
 error = 0;
 
-#ifdef BSWAP_NEEDED
 bswap_ehdr(interp_elf_ex);
-#endif
 /* First of all, some simple consistency checks */
 if ((interp_elf_ex->e_type != ET_EXEC &&
  interp_elf_ex->e_type != ET_DYN) ||
@@ -410,12 +424,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 free(elf_phdata);
 return retval;
 }
-#ifdef BSWAP_NEEDED
-eppnt = elf_phdata;
-for (i = 0; ie_phnum; i++, eppnt++) {
-bswap_phdr(eppnt);
-}
-#endif
+bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
 
 if 

[PATCH v3 31/43] bsd-user: Remove dead #ifdefs from elfload.c

2021-09-02 Thread imp
From: Warner Losh 

LOW_ELF_STACK doesn't exist on FreeBSD and likely never will. Remove it.
Likewise, remove an #if 0 block that's not useful

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 6156f9775d..11ca813c7a 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -558,9 +558,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 abi_ulong elf_entry, interp_load_addr = 0;
 abi_ulong start_code, end_code, start_data, end_data;
 abi_ulong reloc_func_desc = 0;
-#ifdef LOW_ELF_STACK
-abi_ulong elf_stack = ~((abi_ulong)0UL);
-#endif
 
 load_addr = 0;
 load_bias = 0;
@@ -761,11 +758,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 exit(-1);
 }
 
-#ifdef LOW_ELF_STACK
-if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
-elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
-#endif
-
 if (!load_addr_set) {
 load_addr_set = 1;
 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
@@ -823,9 +815,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 close(bprm->fd);
 
-#ifdef LOW_ELF_STACK
-info->start_stack = bprm->p = elf_stack - 4;
-#endif
 bprm->p = target_create_elf_tables(bprm->p, bprm->argc, bprm->envc,
bprm->stringp, _ex, load_addr,
load_bias, interp_load_addr, info);
@@ -843,15 +832,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 padzero(elf_bss, elf_brk);
 
-#if 0
-printf("(start_brk) %x\n" , info->start_brk);
-printf("(end_code) %x\n" , info->end_code);
-printf("(start_code) %x\n" , info->start_code);
-printf("(end_data) %x\n" , info->end_data);
-printf("(start_stack) %x\n" , info->start_stack);
-printf("(brk) %x\n" , info->brk);
-#endif
-
 info->entry = elf_entry;
 
 return 0;
-- 
2.32.0




[PATCH v3 12/43] bsd-user: remove a.out support

2021-09-02 Thread imp
From: Warner Losh 

Remove still-born a.out support. The BSDs switched from a.out to ELF 20+ years
ago. It's out of scope for bsd-user, and what little support there was would
simply wind up at a not-implemented message. Simplify the whole mess by removing
it entirely. Should future support be required, it would be better to start from
scratch.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 bsd-user/bsdload.c |   9 +---
 bsd-user/elfload.c | 105 -
 bsd-user/qemu.h|   2 +-
 3 files changed, 21 insertions(+), 95 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 32f7fd5dec..6aefc7a28b 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -98,7 +98,7 @@ static int prepare_binprm(struct bsd_binprm *bprm)
 
 /* Construct the envp and argv tables on the target stack.  */
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
-  abi_ulong stringp, int push_ptr)
+  abi_ulong stringp)
 {
 int n = sizeof(abi_ulong);
 abi_ulong envp;
@@ -108,13 +108,6 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 envp = sp;
 sp -= (argc + 1) * n;
 argv = sp;
-if (push_ptr) {
-/* FIXME - handle put_user() failures */
-sp -= n;
-put_user_ual(envp, sp);
-sp -= n;
-put_user_ual(argv, sp);
-}
 sp -= n;
 /* FIXME - handle put_user() failures */
 put_user_ual(argc, sp);
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index e950732978..4f3fa83c2c 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -52,25 +52,6 @@
 
 #include "elf.h"
 
-struct exec
-{
-  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
-  unsigned int a_text;   /* length of text, in bytes */
-  unsigned int a_data;   /* length of data, in bytes */
-  unsigned int a_bss;/* length of uninitialized data area, in bytes */
-  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
-  unsigned int a_entry;  /* start address */
-  unsigned int a_trsize; /* length of relocation info for text, in bytes */
-  unsigned int a_drsize; /* length of relocation info for data, in bytes */
-};
-
-
-#define N_MAGIC(exec) ((exec).a_info & 0x)
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define QMAGIC 0314
-
 /* max code+data+bss space allocated to elf interpreter */
 #define INTERP_MAP_SIZE (32 * 1024 * 1024)
 
@@ -82,10 +63,6 @@ struct exec
 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned 
long)(TARGET_ELF_EXEC_PAGESIZE - 1))
 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
 
-#define INTERPRETER_NONE 0
-#define INTERPRETER_AOUT 1
-#define INTERPRETER_ELF 2
-
 #define DLINFO_ITEMS 12
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
@@ -93,8 +70,6 @@ static inline void memcpy_fromfs(void *to, const void *from, 
unsigned long n)
 memcpy(to, from, n);
 }
 
-static int load_aout_interp(void *exptr, int interp_fd);
-
 #ifdef BSWAP_NEEDED
 static void bswap_ehdr(struct elfhdr *ehdr)
 {
@@ -300,7 +275,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
struct elfhdr * exec,
abi_ulong load_addr,
abi_ulong load_bias,
-   abi_ulong interp_load_addr, int ibcs,
+   abi_ulong interp_load_addr,
struct image_info *info)
 {
 abi_ulong sp;
@@ -330,7 +305,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 size += DLINFO_ARCH_ITEMS * 2;
 #endif
 size += envc + argc + 2;
-size += (!ibcs ? 3 : 1);/* argc itself */
+size += 1;/* argc itself */
 size *= n;
 if (size & 15)
 sp -= 16 - (size & 15);
@@ -370,7 +345,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 #endif
 #undef NEW_AUX_ENT
 
-sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
+sp = loader_build_argptr(envc, argc, sp, p);
 return sp;
 }
 
@@ -432,7 +407,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 if (retval < 0) {
 perror("load_elf_interp");
 exit(-1);
-free (elf_phdata);
+free(elf_phdata);
 return retval;
 }
 #ifdef BSWAP_NEEDED
@@ -685,11 +660,9 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 {
 struct elfhdr elf_ex;
 struct elfhdr interp_elf_ex;
-struct exec interp_ex;
 int interpreter_fd = -1; /* avoid warning */
 abi_ulong load_addr, load_bias;
 int load_addr_set = 0;
-unsigned int interpreter_type = INTERPRETER_NONE;
 int i;
 struct elf_phdr * elf_ppnt;
 struct elf_phdr *elf_phdata;

[PATCH v3 17/43] bsd-user: Include host-os.h from main

2021-09-02 Thread imp
From: Warner Losh 

Include host-os.h from main.c to pick up the default OS to emulate.  Set
that default in main().

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/host-os.h | 2 ++
 bsd-user/main.c| 4 +++-
 bsd-user/netbsd/host-os.h  | 2 ++
 bsd-user/openbsd/host-os.h | 2 ++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/bsd-user/freebsd/host-os.h b/bsd-user/freebsd/host-os.h
index bd3f2892db..dfb8344b7b 100644
--- a/bsd-user/freebsd/host-os.h
+++ b/bsd-user/freebsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef _HOST_OS_H_
 #define _HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_freebsd
+
 #endif /*!_HOST_OS_H_ */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index e06cc7b414..607fdd8380 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -41,6 +41,8 @@
 #include "exec/log.h"
 #include "trace/control.h"
 
+#include "host-os.h"
+
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -352,7 +354,7 @@ int main(int argc, char **argv)
 const char *gdbstub = NULL;
 char **target_environ, **wrk;
 envlist_t *envlist = NULL;
-bsd_type = target_openbsd;
+bsd_type = HOST_DEFAULT_BSD_TYPE;
 
 if (argc <= 1) {
 usage();
diff --git a/bsd-user/netbsd/host-os.h b/bsd-user/netbsd/host-os.h
index d4bbc7d58f..c0be51a7ef 100644
--- a/bsd-user/netbsd/host-os.h
+++ b/bsd-user/netbsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef _HOST_OS_H_
 #define _HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_netbsd
+
 #endif /*!_HOST_OS_H_ */
diff --git a/bsd-user/openbsd/host-os.h b/bsd-user/openbsd/host-os.h
index ae23bfef64..eb8fdf1567 100644
--- a/bsd-user/openbsd/host-os.h
+++ b/bsd-user/openbsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef _HOST_OS_H_
 #define _HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_openbsd
+
 #endif /*!_HOST_OS_H_ */
-- 
2.32.0




[PATCH v3 16/43] bsd-user: add host-os.h

2021-09-02 Thread imp
From: Warner Losh 

Host OS specific bits for this implementation go in this file.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/host-os.h | 23 +++
 bsd-user/netbsd/host-os.h  | 23 +++
 bsd-user/openbsd/host-os.h | 23 +++
 3 files changed, 69 insertions(+)
 create mode 100644 bsd-user/freebsd/host-os.h
 create mode 100644 bsd-user/netbsd/host-os.h
 create mode 100644 bsd-user/openbsd/host-os.h

diff --git a/bsd-user/freebsd/host-os.h b/bsd-user/freebsd/host-os.h
new file mode 100644
index 00..bd3f2892db
--- /dev/null
+++ b/bsd-user/freebsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  FreeBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _HOST_OS_H_
+#define _HOST_OS_H_
+
+#endif /*!_HOST_OS_H_ */
diff --git a/bsd-user/netbsd/host-os.h b/bsd-user/netbsd/host-os.h
new file mode 100644
index 00..d4bbc7d58f
--- /dev/null
+++ b/bsd-user/netbsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  NetBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _HOST_OS_H_
+#define _HOST_OS_H_
+
+#endif /*!_HOST_OS_H_ */
diff --git a/bsd-user/openbsd/host-os.h b/bsd-user/openbsd/host-os.h
new file mode 100644
index 00..ae23bfef64
--- /dev/null
+++ b/bsd-user/openbsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  OpenBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _HOST_OS_H_
+#define _HOST_OS_H_
+
+#endif /*!_HOST_OS_H_ */
-- 
2.32.0




[PATCH v3 11/43] bsd-user: Eliminate elf personality

2021-09-02 Thread imp
From: Warner Losh 

The linux kernel supports a number of different ELF binaries. The Linux userland
emulator inheritted some of that. And we inheritted it from there. However, for
BSD there's only one kind of ELF file supported per platform, so there's no need
to cope with historical quirks. Simply the code as a result.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 87 --
 bsd-user/qemu.h|  1 -
 2 files changed, 88 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 639673f5b7..e950732978 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -25,66 +25,6 @@
 
 #include "target_arch_elf.h"
 
-/* from personality.h */
-
-/*
- * Flags for bug emulation.
- *
- * These occupy the top three bytes.
- */
-enum {
-ADDR_NO_RANDOMIZE = 0x004,  /* disable randomization of VA 
space */
-FDPIC_FUNCPTRS =0x008,  /* userspace function ptrs 
point to descriptors
- * (signal handling)
- */
-MMAP_PAGE_ZERO =0x010,
-ADDR_COMPAT_LAYOUT =0x020,
-READ_IMPLIES_EXEC = 0x040,
-ADDR_LIMIT_32BIT =  0x080,
-SHORT_INODE =   0x100,
-WHOLE_SECONDS = 0x200,
-STICKY_TIMEOUTS =   0x400,
-ADDR_LIMIT_3GB =0x800,
-};
-
-/*
- * Personality types.
- *
- * These go in the low byte.  Avoid using the top bit, it will
- * conflict with error returns.
- */
-enum {
-PER_LINUX = 0x,
-PER_LINUX_32BIT =   0x | ADDR_LIMIT_32BIT,
-PER_LINUX_FDPIC =   0x | FDPIC_FUNCPTRS,
-PER_SVR4 =  0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
-PER_SVR3 =  0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_SCOSVR3 =   0x0003 | STICKY_TIMEOUTS |
- WHOLE_SECONDS | SHORT_INODE,
-PER_OSR5 =  0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
-PER_WYSEV386 =  0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
-PER_BSD =   0x0006,
-PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
-PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_LINUX32 =   0x0008,
-PER_LINUX32_3GB =   0x0008 | ADDR_LIMIT_3GB,
-PER_IRIX32 =0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
-PER_IRIXN32 =   0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
-PER_IRIX64 =0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
-PER_RISCOS =0x000c,
-PER_SOLARIS =   0x000d | STICKY_TIMEOUTS,
-PER_UW7 =   0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
-PER_OSF4 =  0x000f,  /* OSF/1 v4 */
-PER_HPUX =  0x0010,
-PER_MASK =  0x00ff,
-};
-
-/*
- * Return the base personality without flags.
- */
-#define personality(pers)   (pers & PER_MASK)
-
 /* this flag is uneffective under linux too, should be deleted */
 #ifndef MAP_DENYWRITE
 #define MAP_DENYWRITE 0
@@ -750,7 +690,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 abi_ulong load_addr, load_bias;
 int load_addr_set = 0;
 unsigned int interpreter_type = INTERPRETER_NONE;
-unsigned char ibcs2_interpreter;
 int i;
 struct elf_phdr * elf_ppnt;
 struct elf_phdr *elf_phdata;
@@ -765,7 +704,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 #endif
 char passed_fileno[6];
 
-ibcs2_interpreter = 0;
 load_addr = 0;
 load_bias = 0;
 elf_ex = *((struct elfhdr *) bprm->buf);  /* exec-header */
@@ -856,20 +794,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 exit(-1);
 }
 
-/* If the program interpreter is one of these two,
-   then assume an iBCS2 image. Otherwise assume
-   a native linux image. */
-
-/* JRP - Need to add X86 lib dir stuff here... */
-
-if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0 ||
-strcmp(elf_interpreter, "/usr/lib/ld.so.1") == 0) {
-  ibcs2_interpreter = 1;
-}
-
-#if 0
-printf("Using ELF interpreter %s\n", path(elf_interpreter));
-#endif
 if (retval >= 0) {
 retval = open(path(elf_interpreter), O_RDONLY);
 if (retval >= 0) {
@@ -1099,7 +1023,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 load_symbols(_ex, bprm->fd);
 
 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
-info->personality = (ibcs2_interpreter ? 

[PATCH v3 26/43] bsd-user: *BSD specific siginfo defintions

2021-09-02 Thread imp
From: Warner Losh 

Add FreeBSD, NetBSD and OpenBSD values for the various signal info types
and defines to decode different signals to discover more information
about the specific signal types.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_siginfo.h | 145 +++
 bsd-user/freebsd/target_os_signal.h  |  78 ++
 bsd-user/i386/target_arch_signal.h   |  94 +
 bsd-user/netbsd/target_os_siginfo.h  |  82 +++
 bsd-user/netbsd/target_os_signal.h   |  69 +
 bsd-user/openbsd/target_os_siginfo.h |  82 +++
 bsd-user/openbsd/target_os_signal.h  |  69 +
 bsd-user/qemu.h  |   1 +
 bsd-user/syscall_defs.h  |  10 --
 bsd-user/x86_64/target_arch_signal.h |  94 +
 10 files changed, 714 insertions(+), 10 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_siginfo.h
 create mode 100644 bsd-user/freebsd/target_os_signal.h
 create mode 100644 bsd-user/i386/target_arch_signal.h
 create mode 100644 bsd-user/netbsd/target_os_siginfo.h
 create mode 100644 bsd-user/netbsd/target_os_signal.h
 create mode 100644 bsd-user/openbsd/target_os_siginfo.h
 create mode 100644 bsd-user/openbsd/target_os_signal.h
 create mode 100644 bsd-user/x86_64/target_arch_signal.h

diff --git a/bsd-user/freebsd/target_os_siginfo.h 
b/bsd-user/freebsd/target_os_siginfo.h
new file mode 100644
index 00..84944faa4d
--- /dev/null
+++ b/bsd-user/freebsd/target_os_siginfo.h
@@ -0,0 +1,145 @@
+/*
+ *  FreeBSD siginfo related definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_OS_SIGINFO_H_
+#define _TARGET_OS_SIGINFO_H_
+
+#define TARGET_NSIG 128
+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8)
+#define TARGET_NSIG_WORDS   (TARGET_NSIG / TARGET_NSIG_BPW)
+
+/* this struct defines a stack used during syscall handling */
+typedef struct target_sigaltstack {
+abi_longss_sp;
+abi_ulong   ss_size;
+abi_longss_flags;
+} target_stack_t;
+
+typedef struct {
+uint32_t __bits[TARGET_NSIG_WORDS];
+} target_sigset_t;
+
+struct target_sigaction {
+abi_ulong   _sa_handler;
+int32_t sa_flags;
+target_sigset_t sa_mask;
+};
+
+typedef union target_sigval {
+int32_t sival_int;
+abi_ulong sival_ptr;
+int32_t sigval_int;
+abi_ulong sigval_ptr;
+} target_sigval_t;
+
+typedef struct target_siginfo {
+int32_t si_signo;   /* signal number */
+int32_t si_errno;   /* errno association */
+int32_t si_code;/* signal code */
+int32_t si_pid; /* sending process */
+int32_t si_uid; /* sender's ruid */
+int32_t si_status;  /* exit value */
+abi_ulong si_addr;  /* faulting instruction */
+union target_sigval si_value;   /* signal value */
+union {
+struct {
+int32_t _trapno;/* machine specific trap code */
+} _fault;
+
+/* POSIX.1b timers */
+struct {
+int32_t _timerid;
+int32_t _overrun;
+} _timer;
+
+struct {
+int32_t _mqd;
+} _mesgp;
+
+/* SIGPOLL */
+struct {
+int _band;  /* POLL_IN, POLL_OUT, POLL_MSG */
+} _poll;
+
+struct {
+abi_long __spare1__;
+int32_t  __spare2_[7];
+} __spare__;
+} _reason;
+} target_siginfo_t;
+
+struct target_sigevent {
+abi_int sigev_notify;
+abi_int sigev_signo;
+target_sigval_t sigev_value;
+union {
+abi_int _threadid;
+
+/*
+ * The kernel (and thus QEMU) never looks at these;
+ * they're only used as part of the ABI between a
+ * userspace program and libc.
+ */
+struct {
+abi_ulong _function;
+abi_ulong _attribute;
+} _sigev_thread;
+abi_ushort _kevent_flags;
+abi_long _pad[8];
+} _sigev_un;
+};
+
+#define target_si_signo si_signo
+#define target_si_code  si_code
+#define target_si_errno si_errno
+#define target_si_addr  si_addr
+
+/* SIGILL si_codes */
+#define TARGET_ILL_ILLOPC   (1) /* Illegal opcode. */
+#define TARGET_ILL_ILLOPN   (2) /* Illegal operand. */
+#define TARGET_ILL_ILLADR   (3) /* Illegal addressing 

[PATCH v3 10/43] bsd-user: implement path searching

2021-09-02 Thread imp
From: Warner Losh 

Use the PATH to find the executable given a bare argument. We need to do
this so we can implement mixing native and emulated binaries (e.g.,
execing a x86 native binary from an emulated arm binary to optimize
parts of the build). By finding the binary, we will know how to exec it.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 36 +++-
 bsd-user/qemu.h|  3 ++-
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 379015c744..32f7fd5dec 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -139,21 +139,55 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 return sp;
 }
 
+static bool is_there(const char *candidate)
+{
+struct stat fin;
+
+/* XXX work around access(2) false positives for superuser */
+if (access(candidate, X_OK) == 0 && stat(candidate, ) == 0 &&
+S_ISREG(fin.st_mode) && (getuid() != 0 ||
+(fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) {
+return true;
+}
+
+return false;
+}
+
 int loader_exec(const char *filename, char **argv, char **envp,
 struct target_pt_regs *regs, struct image_info *infop,
 struct bsd_binprm *bprm)
 {
+char *path, fullpath[PATH_MAX];
 int retval, i;
 
 bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
 for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
 bprm->page[i] = NULL;
 }
-retval = open(filename, O_RDONLY);
+
+if (strchr(filename, '/') != NULL) {
+path = realpath(filename, fullpath);
+if (path == NULL) {
+/* Failed to resolve. */
+return -1;
+}
+if (!is_there(path)) {
+return -1;
+}
+} else {
+path = g_find_program_in_path(filename);
+if (path == NULL) {
+return -1;
+}
+}
+
+retval = open(path, O_RDONLY);
 if (retval < 0) {
+g_free(path);
 return retval;
 }
 
+bprm->fullpath = path;
 bprm->fd = retval;
 bprm->filename = (char *)filename;
 bprm->argc = count(argv);
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5237e35f9c..6b601ce4b5 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -124,7 +124,8 @@ struct bsd_binprm {
 int argc, envc;
 char **argv;
 char **envp;
-char *filename; /* Name of binary */
+char *filename; /* (Given) Name of binary */
+char *fullpath; /* Full path of binary */
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
-- 
2.32.0




[PATCH v3 07/43] bsd-user: move arch specific defines out of elfload.c

2021-09-02 Thread imp
From: Warner Losh 

Move the architecture specific defines to target_arch_elf.h and delete
them from elfload.c. Only retain ifdefs appropriate for i386 and x86_64.
Add the copyright/license comments, and guard ifdefs.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c| 81 +--
 bsd-user/i386/target_arch_elf.h   | 81 +++
 bsd-user/x86_64/target_arch_elf.h | 67 +
 slirp |  2 +-
 4 files changed, 151 insertions(+), 80 deletions(-)
 create mode 100644 bsd-user/i386/target_arch_elf.h
 create mode 100644 bsd-user/x86_64/target_arch_elf.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index fffa24f041..639673f5b7 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,6 +23,8 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
+#include "target_arch_elf.h"
+
 /* from personality.h */
 
 /*
@@ -93,85 +95,6 @@ enum {
 #define ELIBBAD 80
 #endif
 
-#ifdef TARGET_I386
-
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
-static char elf_platform[] = "i386";
-int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6)
-family = 6;
-if (family >= 3)
-elf_platform[1] = '0' + family;
-return elf_platform;
-}
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
-X86CPU *cpu = X86_CPU(thread_cpu);
-
-return cpu->env.features[FEAT_1_EDX];
-}
-
-#ifdef TARGET_X86_64
-#define ELF_START_MMAP 0x2ab000ULL
-#define elf_check_arch(x) (((x) == ELF_ARCH))
-
-#define ELF_CLASS  ELFCLASS64
-#define ELF_DATA   ELFDATA2LSB
-#define ELF_ARCH   EM_X86_64
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->rax = 0;
-regs->rsp = infop->start_stack;
-regs->rip = infop->entry;
-if (bsd_type == target_freebsd) {
-regs->rdi = infop->start_stack;
-}
-}
-
-#else /* !TARGET_X86_64 */
-
-#define ELF_START_MMAP 0x8000
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS   ELFCLASS32
-#define ELF_DATAELFDATA2LSB
-#define ELF_ARCHEM_386
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->esp = infop->start_stack;
-regs->eip = infop->entry;
-
-/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
-   starts %edx contains a pointer to a function which might be
-   registered using `atexit'.  This provides a mean for the
-   dynamic linker to call DT_FINI functions for shared libraries
-   that have been loaded before the code runs.
-
-   A value of 0 tells we have no such handler.  */
-regs->edx = 0;
-}
-#endif /* !TARGET_X86_64 */
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-#endif
-
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
new file mode 100644
index 00..84f61bd930
--- /dev/null
+++ b/bsd-user/i386/target_arch_elf.h
@@ -0,0 +1,81 @@
+/*
+ *  i386 ELF definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_ARCH_ELF_H_
+#define _TARGET_ARCH_ELF_H_
+
+#define ELF_PLATFORM get_elf_platform()
+
+static const char *get_elf_platform(void)
+{
+static char elf_platform[] = "i386";
+int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
+if (family > 6) {
+family = 6;
+}
+if (family >= 3) {
+elf_platform[1] = '0' + family;
+}
+return elf_platform;
+}
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+X86CPU *cpu = X86_CPU(thread_cpu);
+
+return cpu->env.features[FEAT_1_EDX];
+}
+
+#define ELF_START_MMAP 0x8000
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS   

[PATCH v3 29/43] bsd-user: Add architecture specific signal tramp code

2021-09-02 Thread imp
From: Warner Losh 

Add a stubbed out version of setup_sigtramp. This is not yet used for
x86, but is used for other architectures. This will be connected in
future commits.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/target_arch_sigtramp.h   | 29 ++
 bsd-user/x86_64/target_arch_sigtramp.h | 29 ++
 2 files changed, 58 insertions(+)
 create mode 100644 bsd-user/i386/target_arch_sigtramp.h
 create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h

diff --git a/bsd-user/i386/target_arch_sigtramp.h 
b/bsd-user/i386/target_arch_sigtramp.h
new file mode 100644
index 00..cb4e89b0b0
--- /dev/null
+++ b/bsd-user/i386/target_arch_sigtramp.h
@@ -0,0 +1,29 @@
+/*
+ * Intel i386  sigcode for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+unsigned sys_sigreturn)
+{
+
+return 0;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/x86_64/target_arch_sigtramp.h 
b/bsd-user/x86_64/target_arch_sigtramp.h
new file mode 100644
index 00..29d4a8b55f
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_sigtramp.h
@@ -0,0 +1,29 @@
+/*
+ * Intel x86_64  sigcode for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+unsigned sys_sigreturn)
+{
+
+return 0;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
-- 
2.32.0




[PATCH v3 09/43] bsd-user: Fix calculation of size to allocate

2021-09-02 Thread imp
From: Warner Losh 

It was incorrect to subtract off the size of an unsigned int here.  In
bsd-user fork, this change was made when moving the arch specific items
to specific files.  The size in BSD that's available for the arguments
does not need a return address subtracted from it.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/bsdload.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 5282a7c4f2..379015c744 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -143,10 +143,9 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 struct target_pt_regs *regs, struct image_info *infop,
 struct bsd_binprm *bprm)
 {
-int retval;
-int i;
+int retval, i;
 
-bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
+bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
 for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
 bprm->page[i] = NULL;
 }
-- 
2.32.0




[PATCH v3 04/43] bsd-user: add license to bsdload.c

2021-09-02 Thread imp
From: Warner Losh 

Pull in the license statement at the top of the bsdload.c file
from the bsd-user fork version of this file. No functional changes.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/bsdload.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 8d83f21eda..0ade58b9e2 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -1,4 +1,19 @@
-/* Code for loading BSD executables.  Mostly linux kernel code.  */
+/*
+ *  Load BSD executables.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
 
 #include "qemu/osdep.h"
 
-- 
2.32.0




[PATCH v3 20/43] bsd-user: Move per-cpu code into target_arch_cpu.h

2021-09-02 Thread imp
From: Warner Losh 

Move cpu_loop() into target_cpu_loop(), and put that in
target_arch_cpu.h for each architecture.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_cpu.c   |   1 +
 bsd-user/i386/target_arch_cpu.h   | 209 
 bsd-user/main.c   | 317 ++
 bsd-user/qemu.h   |   1 +
 bsd-user/x86_64/target_arch_cpu.c |   1 +
 bsd-user/x86_64/target_arch_cpu.h | 247 +++
 6 files changed, 473 insertions(+), 303 deletions(-)
 create mode 100644 bsd-user/i386/target_arch_cpu.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.h

diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
index 7f2f755a11..71998e5ba5 100644
--- a/bsd-user/i386/target_arch_cpu.c
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -1,6 +1,7 @@
 /*
  *  i386 cpu related code
  *
+ * Copyright (c) 2013 Stacey Son 
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
new file mode 100644
index 00..978e8066af
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -0,0 +1,209 @@
+/*
+ *  i386 cpu init and loop
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "qemu32"
+
+#define TARGET_CPU_RESET(cpu)
+
+static inline void target_cpu_init(CPUX86State *env,
+struct target_pt_regs *regs)
+{
+uint64_t *gdt_table;
+
+env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+env->hflags |= HF_PE_MASK | HF_CPL_MASK;
+if (env->features[FEAT_1_EDX] & CPUID_SSE) {
+env->cr[4] |= CR4_OSFXSR_MASK;
+env->hflags |= HF_OSFXSR_MASK;
+}
+
+/* flags setup : we activate the IRQs by default as in user mode */
+env->eflags |= IF_MASK;
+
+/* register setup */
+env->regs[R_EAX] = regs->eax;
+env->regs[R_EBX] = regs->ebx;
+env->regs[R_ECX] = regs->ecx;
+env->regs[R_EDX] = regs->edx;
+env->regs[R_ESI] = regs->esi;
+env->regs[R_EDI] = regs->edi;
+env->regs[R_EBP] = regs->ebp;
+env->regs[R_ESP] = regs->esp;
+env->eip = regs->eip;
+
+/* interrupt setup */
+env->idt.limit = 255;
+
+env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+bsd_i386_set_idt_base(env->idt.base);
+bsd_i386_set_idt(0, 0);
+bsd_i386_set_idt(1, 0);
+bsd_i386_set_idt(2, 0);
+bsd_i386_set_idt(3, 3);
+bsd_i386_set_idt(4, 3);
+bsd_i386_set_idt(5, 0);
+bsd_i386_set_idt(6, 0);
+bsd_i386_set_idt(7, 0);
+bsd_i386_set_idt(8, 0);
+bsd_i386_set_idt(9, 0);
+bsd_i386_set_idt(10, 0);
+bsd_i386_set_idt(11, 0);
+bsd_i386_set_idt(12, 0);
+bsd_i386_set_idt(13, 0);
+bsd_i386_set_idt(14, 0);
+bsd_i386_set_idt(15, 0);
+bsd_i386_set_idt(16, 0);
+bsd_i386_set_idt(17, 0);
+bsd_i386_set_idt(18, 0);
+bsd_i386_set_idt(19, 0);
+bsd_i386_set_idt(0x80, 3);
+
+/* segment setup */
+env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
+gdt_table = g2h_untagged(env->gdt.base);
+
+bsd_i386_write_dt(_table[__USER_CS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
+
+bsd_i386_write_dt(_table[__USER_DS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
+
+cpu_x86_load_seg(env, R_CS, __USER_CS);
+cpu_x86_load_seg(env, R_SS, __USER_DS);
+cpu_x86_load_seg(env, R_DS, __USER_DS);
+cpu_x86_load_seg(env, R_ES, __USER_DS);
+cpu_x86_load_seg(env, R_FS, __USER_DS);
+cpu_x86_load_seg(env, R_GS, __USER_DS);
+/* This hack makes Wine work... */
+env->segs[R_FS].selector = 0;
+}
+
+static inline void target_cpu_loop(CPUX86State *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr;
+abi_ulong 

[PATCH v3 08/43] bsd-user: pass the bsd_param into loader_exec

2021-09-02 Thread imp
From: Warner Losh 

Pass the bsd_param into loader_exec, and adjust. We use it to track the
inital stack allocation and to set stack, open files, and other state
shared between bsdload.c and elfload.c

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 bsd-user/bsdload.c | 37 +++--
 bsd-user/main.c|  7 ++-
 bsd-user/qemu.h|  3 ++-
 3 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index ec71c5e923..5282a7c4f2 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -140,35 +140,36 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 }
 
 int loader_exec(const char *filename, char **argv, char **envp,
-struct target_pt_regs *regs, struct image_info *infop)
+struct target_pt_regs *regs, struct image_info *infop,
+struct bsd_binprm *bprm)
 {
-struct bsd_binprm bprm;
 int retval;
 int i;
 
-bprm.p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
-for (i = 0 ; i < MAX_ARG_PAGES ; i++) { /* clear page-table */
-bprm.page[i] = NULL;
+bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
+for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
+bprm->page[i] = NULL;
 }
 retval = open(filename, O_RDONLY);
 if (retval < 0) {
 return retval;
 }
-bprm.fd = retval;
-bprm.filename = (char *)filename;
-bprm.argc = count(argv);
-bprm.argv = argv;
-bprm.envc = count(envp);
-bprm.envp = envp;
 
-retval = prepare_binprm();
+bprm->fd = retval;
+bprm->filename = (char *)filename;
+bprm->argc = count(argv);
+bprm->argv = argv;
+bprm->envc = count(envp);
+bprm->envp = envp;
+
+retval = prepare_binprm(bprm);
 
 if (retval >= 0) {
-if (bprm.buf[0] == 0x7f
-&& bprm.buf[1] == 'E'
-&& bprm.buf[2] == 'L'
-&& bprm.buf[3] == 'F') {
-retval = load_elf_binary(, regs, infop);
+if (bprm->buf[0] == 0x7f
+&& bprm->buf[1] == 'E'
+&& bprm->buf[2] == 'L'
+&& bprm->buf[3] == 'F') {
+retval = load_elf_binary(bprm, regs, infop);
 } else {
 fprintf(stderr, "Unknown binary format\n");
 return -1;
@@ -183,7 +184,7 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 
 /* Something went wrong, return the inode and free the argument pages*/
 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-g_free(bprm.page[i]);
+g_free(bprm->page[i]);
 }
 return retval;
 }
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 39c4a0f33c..1388c7a13d 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -343,6 +343,7 @@ int main(int argc, char **argv)
 const char *log_mask = NULL;
 struct target_pt_regs regs1, *regs = 
 struct image_info info1, *info = 
+struct bsd_binprm bprm;
 TaskState ts1, *ts = 
 CPUArchState *env;
 CPUState *cpu;
@@ -499,6 +500,9 @@ int main(int argc, char **argv)
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
+/* Zero bsd params */
+memset(, 0, sizeof(bprm));
+
 /* Zero out image_info */
 memset(info, 0, sizeof(struct image_info));
 
@@ -566,7 +570,8 @@ int main(int argc, char **argv)
 }
 }
 
-if (loader_exec(filename, argv + optind, target_environ, regs, info) != 0) 
{
+if (loader_exec(filename, argv + optind, target_environ, regs, info,
+) != 0) {
 printf("Error loading %s\n", filename);
 _exit(1);
 }
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index c02e8a5ca1..5237e35f9c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -131,7 +131,8 @@ void do_init_thread(struct target_pt_regs *regs, struct 
image_info *infop);
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
   abi_ulong stringp, int push_ptr);
 int loader_exec(const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop);
+struct target_pt_regs *regs, struct image_info *infop,
+struct bsd_binprm *bprm);
 
 int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 struct image_info *info);
-- 
2.32.0




[PATCH v3 05/43] bsd-user: style nits: bsdload.c whitespace to qemu standard

2021-09-02 Thread imp
From: Warner Losh 

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/bsdload.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 0ade58b9e2..ec71c5e923 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -140,7 +140,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong 
sp,
 }
 
 int loader_exec(const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop)
+struct target_pt_regs *regs, struct image_info *infop)
 {
 struct bsd_binprm bprm;
 int retval;
@@ -148,7 +148,7 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 
 bprm.p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
 for (i = 0 ; i < MAX_ARG_PAGES ; i++) { /* clear page-table */
-bprm.page[i] = NULL;
+bprm.page[i] = NULL;
 }
 retval = open(filename, O_RDONLY);
 if (retval < 0) {
-- 
2.32.0




[PATCH v3 02/43] bsd-user: add copyright header to elfload.c

2021-09-02 Thread imp
From: Warner Losh 

Add Stacey's copyright to elfload.c

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 6edceb3ea6..ae62f3aab3 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -1,4 +1,21 @@
-/* This is the Linux kernel elf-loading code, ported into user space */
+/*
+ *  ELF loading code
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
 
 #include "qemu/osdep.h"
 
-- 
2.32.0




[PATCH v3 01/43] bsd-user: remove sparc and sparc64

2021-09-02 Thread imp
From: Warner Losh 

These are broken here and in the bsd-user fork. They won't be fixed as
FreeBSD has dropped support for sparc. If people wish to support this in
other BSDs, you're better off starting over than starting from these
files.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c| 289 -
 bsd-user/sparc/target_arch_sysarch.h   |  52 -
 bsd-user/sparc/target_syscall.h|  36 ---
 bsd-user/sparc64/target_arch_sysarch.h |  52 -
 bsd-user/sparc64/target_syscall.h  |  37 
 bsd-user/syscall.c |  11 -
 6 files changed, 477 deletions(-)
 delete mode 100644 bsd-user/sparc/target_arch_sysarch.h
 delete mode 100644 bsd-user/sparc/target_syscall.h
 delete mode 100644 bsd-user/sparc64/target_arch_sysarch.h
 delete mode 100644 bsd-user/sparc64/target_syscall.h

diff --git a/bsd-user/main.c b/bsd-user/main.c
index fe66204b6b..38185da111 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -261,274 +261,6 @@ void cpu_loop(CPUX86State *env)
 }
 #endif
 
-#ifdef TARGET_SPARC
-#define SPARC64_STACK_BIAS 2047
-
-/* #define DEBUG_WIN */
-/*
- * WARNING: dealing with register windows _is_ complicated. More info
- * can be found at http://www.sics.se/~psm/sparcstack.html
- */
-static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
-{
-index = (index + cwp * 16) % (16 * env->nwindows);
-/*
- * wrap handling : if cwp is on the last window, then we use the
- * registers 'after' the end
- */
-if (index < 8 && env->cwp == env->nwindows - 1) {
-index += 16 * env->nwindows;
-}
-return index;
-}
-
-/* save the register window 'cwp1' */
-static inline void save_window_offset(CPUSPARCState *env, int cwp1)
-{
-unsigned int i;
-abi_ulong sp_ptr;
-
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3) {
-sp_ptr += SPARC64_STACK_BIAS;
-}
-#endif
-#if defined(DEBUG_WIN)
-printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for (i = 0; i < 16; i++) {
-/* FIXME - what to do if put_user() fails? */
-put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-}
-
-static void save_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-env->wim = new_wim;
-#else
-/*
- * cansave is zero if the spill trap handler is triggered by `save` and
- * nonzero if triggered by a `flushw`
- */
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
-env->cansave++;
-env->canrestore--;
-#endif
-}
-
-static void restore_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-#endif
-unsigned int i, cwp1;
-abi_ulong sp_ptr;
-
-#ifndef TARGET_SPARC64
-new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-#endif
-
-/* restore the invalid window */
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3) {
-sp_ptr += SPARC64_STACK_BIAS;
-}
-#endif
-#if defined(DEBUG_WIN)
-printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for (i = 0; i < 16; i++) {
-/* FIXME - what to do if get_user() fails? */
-get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-#ifdef TARGET_SPARC64
-env->canrestore++;
-if (env->cleanwin < env->nwindows - 1) {
-env->cleanwin++;
-}
-env->cansave--;
-#else
-env->wim = new_wim;
-#endif
-}
-
-static void flush_windows(CPUSPARCState *env)
-{
-int offset, cwp1;
-
-offset = 1;
-for (;;) {
-/* if restore would invoke restore_window(), then we can stop */
-cwp1 = cpu_cwp_inc(env, env->cwp + offset);
-#ifndef TARGET_SPARC64
-if (env->wim & (1 << cwp1)) {
-break;
-}
-#else
-if (env->canrestore == 0) {
-break;
-}
-env->cansave++;
-env->canrestore--;
-#endif
-save_window_offset(env, cwp1);
-offset++;
-}
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-#ifndef TARGET_SPARC64
-/* set wim so that restore will reload the registers */
-env->wim = 1 << cwp1;
-#endif
-#if defined(DEBUG_WIN)
-printf("flush_windows: nb=%d\n", offset - 1);
-#endif
-}
-
-void cpu_loop(CPUSPARCState *env)
-{
-CPUState *cs = env_cpu(env);
-int trapnr, ret, syscall_nr;
-/* target_siginfo_t info; */
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = 

[PATCH v3 00/43] bsd-user updates to run hello world

2021-09-02 Thread imp
From: Warner Losh 

This series of patches gets me to the point that I can run "Hello World" on i386
and x86_64. This is for static binaries only, that are relatively small, but
it's better than the 100% instant mmap failre that is the current state of all
things bsd-user in upstream qemu. Future patch sets will refine this, add
the missing system calls, fix bugs preventing more sophisticated programms
from running and add a bunch of new architecture support.

There's three large themes in these patches, though the changes that
represent them are interrelated making it hard to separate out further.
1. Reorganization to support multiple OS and architectures (though I've only
   tested FreeBSD, other BSDs might not even compile yet).
2. Diff reduction with the bsd-user fork for several files. These diffs include
   changes that borrowed from linux-user as well as changes to make things work
   on FreeBSD. The records keeping when this was done, however, was poor at
   best, so many of the specific borrowings are going unacknowledged here, apart
   from this general ack. These diffs also include some minor code shuffling.
   Some of the changes are done specifically to make it easier to rebase
   the bsd-user fork's changes when these land in the tree (a number of changes
   have been pushed there to make this more possible).
3. Filling in the missing pieces to make things work. There's many changes to
   elfload to make it load things in the right places, to find the interpreter
   better, etc. There's changes to mmap.c to make the mappings work better and
   there's changes to main.c that were inspired, at least, by now-ancient 
changes
   to linux-user's main.c.

I ran checkpatch.pl on this, and there's 350-odd errors it identifies (the vast
majoirty come from BSD's fetish for tabs), so there will need to be a V2 to fix
this at the very least. In addition, the change set is big (about +~4.5k/-~2.5k
lines), so I anticipate some iteration as well just based on its sheer
size. I've tried to keep each set small to make it easy to review in isolation,
but I've also allowed some interrelated ones to get a little bigger than I'd
normally like. I've not done the customary documentation of the expected
checkpatch.pl output because it is large, and because I wanted to get review
of the other parts rolling to get this project unstuck. Future versions of the
patch will document the expected output.

In addition, I noticed a number of places where I could modernize to make the
code match things like linux-user better. I've resisted the urge to do these at
this time, since it would complicate merging the other ~30k lines of diff that
remains after this batch. Future batches should generally be smaller once this
one has landed since they are, by and large, either a bunch of new files to
support armv7, aarch64, riscv64, mips, mipsel, mips64, ppc, ppc64 and ppc64le,
or are adding system calls, which can be done individually or small groups. I've
removed sparc and sparc64 support as they've been removed from FreeBSD and
have been near totally busted for years.

Stacey Son did the bulk of this work originally, but since I had to move things
around so much and/or retool that work in non-trivial ways, I've kept myself as
author, and added his signed-off-by line. I'm unsure of the qemu standard
practice for this, but am happy to learn if this is too far outside its current
mainstream. For a while Sean Bruno did the merges from upstream, and he's
credited using his signed-off-by in appropriate places, though for this patch
set there's only a few. I've tried to ensure that others who have work in
individual patches that I've aggregated together also are reflected in their
signed-off-by. Given the chaotic stat of the upstream repo for its early
history, this may be the best that can be reconstructed at this late date. Most
of these files are 'foundational' so have existed from the earliest days when
record keeping wasn't quite what I'd wish for in hindsight. There was only
really one change that I could easily cherry-pick (Colin's), so I did that.

v2: rejected patches dropped
Use suggested glibc routines
Updated to be closer to qemu style
Disable bsd-user on netbsd and openbsd since they don't compile
fold together a couple of related changes
[[ tagged the review-by and acked-by from last series, but by hand...
  I think I got them all... ]]

v3: Fix a bug in refactoring load_elf_sections and is_target_elf_binary
Fix spelling errors in commit messages
drop copy_cpu() patch until we use that function
reword a few commit messages to make them clearer
fix return value of setup_sigtramp to be 0 after #ifdef elimination
Add patch to initialize random state and implement --seed
Fix a boatload of style issues.
Rebase to tip of master

NOTE: checkpatch.pl will have several warning about line length > 80 and
admonishment to not use architecture specific defines. The slightly long lines

[PATCH v3 06/43] bsd-user: Remove all non-x86 code from elfload.c

2021-09-02 Thread imp
From: Warner Losh 

bsd-user only builds x86 at the moment. Remove all non x86 code from
elfload.c. We'll move the x86 code to {i386,x86_64}/target_arch_elf.h
and bring it that support code from the forked bsd-user when the time
comes.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 347 +
 1 file changed, 2 insertions(+), 345 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index ae62f3aab3..fffa24f041 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,15 +23,6 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
-#ifdef _ARCH_PPC64
-#undef ARCH_DLINFO
-#undef ELF_PLATFORM
-#undef ELF_HWCAP
-#undef ELF_CLASS
-#undef ELF_DATA
-#undef ELF_ARCH
-#endif
-
 /* from personality.h */
 
 /*
@@ -144,7 +135,7 @@ static inline void init_thread(struct target_pt_regs *regs, 
struct image_info *i
 }
 }
 
-#else
+#else /* !TARGET_X86_64 */
 
 #define ELF_START_MMAP 0x8000
 
@@ -174,343 +165,13 @@ static inline void init_thread(struct target_pt_regs 
*regs, struct image_info *i
A value of 0 tells we have no such handler.  */
 regs->edx = 0;
 }
-#endif
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-#endif
-
-#ifdef TARGET_ARM
-
-#define ELF_START_MMAP 0x8000
-
-#define elf_check_arch(x) ((x) == EM_ARM)
-
-#define ELF_CLASS   ELFCLASS32
-#ifdef TARGET_WORDS_BIGENDIAN
-#define ELF_DATAELFDATA2MSB
-#else
-#define ELF_DATAELFDATA2LSB
-#endif
-#define ELF_ARCHEM_ARM
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-abi_long stack = infop->start_stack;
-memset(regs, 0, sizeof(*regs));
-regs->ARM_cpsr = 0x10;
-if (infop->entry & 1)
-regs->ARM_cpsr |= CPSR_T;
-regs->ARM_pc = infop->entry & 0xfffe;
-regs->ARM_sp = infop->start_stack;
-/* FIXME - what to for failure of get_user()? */
-get_user_ual(regs->ARM_r2, stack + 8); /* envp */
-get_user_ual(regs->ARM_r1, stack + 4); /* envp */
-/* XXX: it seems that r0 is zeroed after ! */
-regs->ARM_r0 = 0;
-/* For uClinux PIC binaries.  */
-/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
-regs->ARM_r10 = infop->start_data;
-}
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-enum
-{
-  ARM_HWCAP_ARM_SWP   = 1 << 0,
-  ARM_HWCAP_ARM_HALF  = 1 << 1,
-  ARM_HWCAP_ARM_THUMB = 1 << 2,
-  ARM_HWCAP_ARM_26BIT = 1 << 3,
-  ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
-  ARM_HWCAP_ARM_FPA   = 1 << 5,
-  ARM_HWCAP_ARM_VFP   = 1 << 6,
-  ARM_HWCAP_ARM_EDSP  = 1 << 7,
-};
-
-#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF  \
-| ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
-| ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
-
-#endif
-
-#ifdef TARGET_SPARC
-#ifdef TARGET_SPARC64
-
-#define ELF_START_MMAP 0x8000
-
-#ifndef TARGET_ABI32
-#define elf_check_arch(x) ((x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS)
-#else
-#define elf_check_arch(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
-#endif
-
-#define ELF_CLASS   ELFCLASS64
-#define ELF_DATAELFDATA2MSB
-#define ELF_ARCHEM_SPARCV9
-
-#define STACK_BIAS  2047
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-#ifndef TARGET_ABI32
-regs->tstate = 0;
-#endif
-regs->pc = infop->entry;
-regs->npc = regs->pc + 4;
-regs->y = 0;
-#ifdef TARGET_ABI32
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-#else
-if (personality(infop->personality) == PER_LINUX32)
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-else {
-regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
-if (bsd_type == target_freebsd) {
-regs->u_regs[8] = infop->start_stack;
-regs->u_regs[11] = infop->start_stack;
-}
-}
-#endif
-}
-
-#else
-#define ELF_START_MMAP 0x8000
-
-#define elf_check_arch(x) ((x) == EM_SPARC)
-
-#define ELF_CLASS   ELFCLASS32
-#define ELF_DATAELFDATA2MSB
-#define ELF_ARCHEM_SPARC
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->psr = 0;
-regs->pc = infop->entry;
-regs->npc = regs->pc + 4;
-regs->y = 0;
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-}
-
-#endif
-#endif
-
-#ifdef TARGET_PPC
-
-#define ELF_START_MMAP 0x8000
-
-#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
-
-#define elf_check_arch(x) ((x) == EM_PPC64)
-
-#define ELF_CLASS   ELFCLASS64
-
-#else
-
-#define elf_check_arch(x) ((x) == EM_PPC)
-
-#define ELF_CLASS   ELFCLASS32
-
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-#define ELF_DATAELFDATA2MSB
-#else
-#define ELF_DATAELFDATA2LSB
-#endif
-#define ELF_ARCHEM_PPC
-
-/*
- * We need to put in some extra aux table entries to tell glibc what
- * the cache block size is, so it 

[PATCH v3 03/43] bsd-user: Add Stacey's copyright to main.c

2021-09-02 Thread imp
From: Warner Losh 

Add Stacey's updated copyright to main.c

Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 38185da111..39c4a0f33c 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1,7 +1,8 @@
 /*
- *  qemu user main
+ *  qemu bsd user main
  *
  *  Copyright (c) 2003-2008 Fabrice Bellard
+ *  Copyright (c) 2013-14 Stacey Son
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
-- 
2.32.0




[PATCH v2 1/2] hw/timer: Add SiFive PWM support

2021-09-02 Thread Alistair Francis
From: Alistair Francis 

This is the initial commit of the SiFive PWM timer. This is used by
guest software are a timer and is included in the SiFive FU540 SoC.

Signed-off-by: Justin Restivo 
Signed-off-by: Alexandra Clifford 
Signed-off-by: Amanda Strnad 
Signed-off-by: Alistair Francis 
---
 include/hw/timer/sifive_pwm.h |  62 +
 hw/timer/sifive_pwm.c | 467 ++
 hw/timer/Kconfig  |   3 +
 hw/timer/meson.build  |   1 +
 hw/timer/trace-events |   6 +
 5 files changed, 539 insertions(+)
 create mode 100644 include/hw/timer/sifive_pwm.h
 create mode 100644 hw/timer/sifive_pwm.c

diff --git a/include/hw/timer/sifive_pwm.h b/include/hw/timer/sifive_pwm.h
new file mode 100644
index 00..e8bedca76e
--- /dev/null
+++ b/include/hw/timer/sifive_pwm.h
@@ -0,0 +1,62 @@
+/*
+ * SiFive FU540 PWM
+ *
+ * Copyright (c) 2020 Western Digital
+ *
+ * Author:  Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_SIFIVE_PWM_H
+#define HW_SIFIVE_PWM_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "qom/object.h"
+
+#define TYPE_SIFIVE_PWM "sifive-pwm"
+
+#define SIFIVE_PWM(obj) \
+OBJECT_CHECK(SiFiveUPwmState, (obj), TYPE_SIFIVE_PWM)
+
+#define SIFIVE_PWM_CHANS  4
+#define SIFIVE_PWM_IRQS   SIFIVE_PWM_CHANS
+
+typedef struct SiFiveUPwmState {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion mmio;
+QEMUTimer timer[SIFIVE_PWM_CHANS];
+/*
+ * if en bit(s) set, is the number of ticks when pwmcount was 0
+ * if en bit(s) not set, is the number of ticks in pwmcount
+ */
+uint64_t tick_offset;
+uint64_t freq_hz;
+
+uint32_t pwmcfg;
+uint32_t pwmcmp[SIFIVE_PWM_CHANS];
+
+qemu_irq irqs[SIFIVE_PWM_IRQS];
+} SiFiveUPwmState;
+
+#endif /* HW_SIFIVE_PWM_H */
diff --git a/hw/timer/sifive_pwm.c b/hw/timer/sifive_pwm.c
new file mode 100644
index 00..61a97f9b46
--- /dev/null
+++ b/hw/timer/sifive_pwm.c
@@ -0,0 +1,467 @@
+/*
+ * SiFive PWM
+ *
+ * Copyright (c) 2020 Western Digital
+ *
+ * Author:  Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/timer/sifive_pwm.h"
+#include "hw/qdev-properties.h"
+#include "hw/registerfields.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+
+#define HAS_PWM_EN_BITS(cfg) ((cfg & R_CONFIG_ENONESHOT_MASK) || \
+  (cfg & R_CONFIG_ENALWAYS_MASK))
+
+#define PWMCMP_MASK 0x
+#define PWMCOUNT_MASK 0x7FFF
+
+REG32(CONFIG,   0x00)
+FIELD(CONFIG, SCALE,0, 4)
+FIELD(CONFIG, STICKY,   8, 1)
+FIELD(CONFIG, ZEROCMP,  9, 1)
+FIELD(CONFIG, DEGLITCH, 10, 1)
+FIELD(CONFIG, ENALWAYS, 12, 1)
+FIELD(CONFIG, ENONESHOT,

[PATCH v2 2/2] sifive_u: Connect the SiFive PWM device

2021-09-02 Thread Alistair Francis
From: Alistair Francis 

Connect the SiFive PWM device and expose it via the device tree.

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/sifive_u.h | 14 +-
 hw/riscv/sifive_u.c | 55 -
 hw/timer/sifive_pwm.c   |  1 +
 hw/riscv/Kconfig|  1 +
 4 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 2656b39808..0d010c7309 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -27,6 +27,7 @@
 #include "hw/misc/sifive_u_otp.h"
 #include "hw/misc/sifive_u_prci.h"
 #include "hw/ssi/sifive_spi.h"
+#include "hw/timer/sifive_pwm.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -49,6 +50,7 @@ typedef struct SiFiveUSoCState {
 SiFiveSPIState spi0;
 SiFiveSPIState spi2;
 CadenceGEMState gem;
+SiFiveUPwmState pwm[2];
 
 uint32_t serial;
 char *cpu_type;
@@ -92,7 +94,9 @@ enum {
 SIFIVE_U_DEV_FLASH0,
 SIFIVE_U_DEV_DRAM,
 SIFIVE_U_DEV_GEM,
-SIFIVE_U_DEV_GEM_MGMT
+SIFIVE_U_DEV_GEM_MGMT,
+SIFIVE_U_DEV_PWM0,
+SIFIVE_U_DEV_PWM1
 };
 
 enum {
@@ -126,6 +130,14 @@ enum {
 SIFIVE_U_PDMA_IRQ5 = 28,
 SIFIVE_U_PDMA_IRQ6 = 29,
 SIFIVE_U_PDMA_IRQ7 = 30,
+SIFIVE_U_DEV_PWM0_0 = 42,
+SIFIVE_U_DEV_PWM0_1 = 43,
+SIFIVE_U_DEV_PWM0_2 = 44,
+SIFIVE_U_DEV_PWM0_3 = 45,
+SIFIVE_U_DEV_PWM1_0 = 46,
+SIFIVE_U_DEV_PWM1_1 = 47,
+SIFIVE_U_DEV_PWM1_2 = 48,
+SIFIVE_U_DEV_PWM1_3 = 49,
 SIFIVE_U_QSPI0_IRQ = 51,
 SIFIVE_U_GEM_IRQ = 53
 };
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6cc1a62b0f..ed2e75df36 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -17,6 +17,7 @@
  * 7) DMA (Direct Memory Access Controller)
  * 8) SPI0 connected to an SPI flash
  * 9) SPI2 connected to an SD card
+ * 10) PWM0 and PWM1
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -75,6 +76,8 @@ static const MemMapEntry sifive_u_memmap[] = {
 [SIFIVE_U_DEV_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
+[SIFIVE_U_DEV_PWM0] = { 0x1002, 0x1000 },
+[SIFIVE_U_DEV_PWM1] = { 0x10021000, 0x1000 },
 [SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
 [SIFIVE_U_DEV_QSPI2] ={ 0x1005, 0x1000 },
 [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
@@ -441,6 +444,38 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
+nodename = g_strdup_printf("/soc/pwm@%lx",
+(long)memmap[SIFIVE_U_DEV_PWM0].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_DEV_PWM0].base,
+0x0, memmap[SIFIVE_U_DEV_PWM0].size);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
+   SIFIVE_U_DEV_PWM0_0, SIFIVE_U_DEV_PWM0_1,
+   SIFIVE_U_DEV_PWM0_2, SIFIVE_U_DEV_PWM0_3);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+   prci_phandle, PRCI_CLK_TLCLK);
+qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
+g_free(nodename);
+
+nodename = g_strdup_printf("/soc/pwm@%lx",
+(long)memmap[SIFIVE_U_DEV_PWM1].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_DEV_PWM1].base,
+0x0, memmap[SIFIVE_U_DEV_PWM1].size);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
+   SIFIVE_U_DEV_PWM1_0, SIFIVE_U_DEV_PWM1_1,
+   SIFIVE_U_DEV_PWM1_2, SIFIVE_U_DEV_PWM1_3);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+   prci_phandle, PRCI_CLK_TLCLK);
+qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_DEV_UART1].base);
 qemu_fdt_add_subnode(fdt, nodename);
@@ -765,6 +800,8 @@ static void sifive_u_soc_instance_init(Object *obj)
 object_initialize_child(obj, "pdma", >dma, TYPE_SIFIVE_PDMA);
 object_initialize_child(obj, "spi0", >spi0, TYPE_SIFIVE_SPI);
 object_initialize_child(obj, "spi2", >spi2, TYPE_SIFIVE_SPI);
+object_initialize_child(obj, "pwm0", >pwm[0], TYPE_SIFIVE_PWM);
+object_initialize_child(obj, "pwm1", >pwm[1], TYPE_SIFIVE_PWM);
 }
 
 static void 

[PATCH v1 1/2] target/riscv: Implement the stval/mtval illegal instruction

2021-09-02 Thread Alistair Francis
From: Alistair Francis 

The stval and mtval registers can optionally contain the faulting
instruction on an illegal instruction exception. This patch adds support
for setting the stval and mtval registers based on the CPU feature.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  5 -
 target/riscv/cpu_helper.c |  9 +
 target/riscv/translate.c  | 33 +++--
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bf1c899c00..6d41a16ae3 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -77,7 +77,8 @@ enum {
 RISCV_FEATURE_MMU,
 RISCV_FEATURE_PMP,
 RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA
+RISCV_FEATURE_MISA,
+RISCV_FEATURE_MTVAL_INST,
 };
 
 #define PRIV_VERSION_1_10_0 0x00011000
@@ -130,6 +131,8 @@ struct CPURISCVState {
 target_ulong frm;
 
 target_ulong badaddr;
+target_ulong bins;
+
 target_ulong guest_phys_fault_addr;
 
 target_ulong priv_ver;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 968cb8046f..42edd71c1e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -967,6 +967,15 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 write_tval  = true;
 tval = env->badaddr;
 break;
+case RISCV_EXCP_ILLEGAL_INST:
+if (riscv_feature(env, RISCV_FEATURE_MTVAL_INST)) {
+/* The stval/mtval register can optionally also be used to
+ * return the faulting instruction bits on an illegal
+ * instruction exception.
+ */
+tval = env->bins;
+}
+break;
 default:
 break;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e356fc6c46..4221d8e2d5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -173,8 +173,27 @@ static void lookup_and_goto_ptr(DisasContext *ctx)
 }
 }
 
+/*
+ * Wrappers for getting reg values.
+ *
+ * The $zero register does not have cpu_gpr[0] allocated -- we supply the
+ * constant zero as a source, and an uninitialized sink as destination.
+ *
+ * Further, we may provide an extension for word operations.
+ */
+static TCGv temp_new(DisasContext *ctx)
+{
+assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
+return ctx->temp[ctx->ntemp++] = tcg_temp_new();
+}
+
 static void gen_exception_illegal(DisasContext *ctx)
 {
+TCGv tmp = temp_new(ctx);
+
+tcg_gen_movi_tl(tmp, ctx->opcode);
+tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, bins));
+
 generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
 }
 
@@ -195,20 +214,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 }
 }
 
-/*
- * Wrappers for getting reg values.
- *
- * The $zero register does not have cpu_gpr[0] allocated -- we supply the
- * constant zero as a source, and an uninitialized sink as destination.
- *
- * Further, we may provide an extension for word operations.
- */
-static TCGv temp_new(DisasContext *ctx)
-{
-assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
-return ctx->temp[ctx->ntemp++] = tcg_temp_new();
-}
-
 static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
 {
 TCGv t;
-- 
2.31.1




[PATCH v2 0/2] Add the SiFive PWM device

2021-09-02 Thread Alistair Francis
From: Alistair Francis 


This series adds a the SiFive PWM device and connects it to the
sifive_u machine. This has been tested as a timer with seL4.

v2:
 - Address Bin's comments
 - Expose PWM via the device tree


Alistair Francis (2):
  hw/timer: Add SiFive PWM support
  sifive_u: Connect the SiFive PWM device

 include/hw/riscv/sifive_u.h   |  14 +-
 include/hw/timer/sifive_pwm.h |  62 +
 hw/riscv/sifive_u.c   |  55 +++-
 hw/timer/sifive_pwm.c | 468 ++
 hw/riscv/Kconfig  |   1 +
 hw/timer/Kconfig  |   3 +
 hw/timer/meson.build  |   1 +
 hw/timer/trace-events |   6 +
 8 files changed, 608 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/timer/sifive_pwm.h
 create mode 100644 hw/timer/sifive_pwm.c

-- 
2.31.1




[PATCH v1 2/2] target/riscv: Set mtval and stval support

2021-09-02 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 +
 target/riscv/cpu.c | 6 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6d41a16ae3..64ebb593fb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -309,6 +309,7 @@ struct RISCVCPU {
 bool mmu;
 bool pmp;
 bool epmp;
+bool mtval_inst;
 uint64_t resetvec;
 } cfg;
 };
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1a2b03d579..8b77526c79 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -437,6 +437,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.mtval_inst) {
+set_feature(env, RISCV_FEATURE_MTVAL_INST);
+}
+
 set_resetvec(env, cpu->cfg.resetvec);
 
 /* If only XLEN is set for misa, then set misa from properties */
@@ -600,7 +604,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-
+DEFINE_PROP_BOOL("mtval_inst", RISCVCPU, cfg.mtval_inst, true),
 DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.31.1




[PATCH v1 0/2] RISC-V: Populate mtval and stval

2021-09-02 Thread Alistair Francis
From: Alistair Francis 


Populate mtval and stval when taking an illegal instruction exception if
the features are set for the CPU.



Alistair Francis (2):
  target/riscv: Implement the stval/mtval illegal instruction
  target/riscv: Set mtval and stval support

 target/riscv/cpu.h|  6 +-
 target/riscv/cpu.c|  6 +-
 target/riscv/cpu_helper.c |  9 +
 target/riscv/translate.c  | 33 +++--
 4 files changed, 38 insertions(+), 16 deletions(-)

-- 
2.31.1




Re: [PATCH v4 7/9] migration: Simplify alignment and alignment checks

2021-09-02 Thread Peter Xu
On Thu, Sep 02, 2021 at 03:14:30PM +0200, David Hildenbrand wrote:
> diff --git a/migration/migration.c b/migration/migration.c
> index bb909781b7..ae97c2c461 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -391,7 +391,7 @@ int 
> migrate_send_rp_message_req_pages(MigrationIncomingState *mis,
>  int migrate_send_rp_req_pages(MigrationIncomingState *mis,
>RAMBlock *rb, ram_addr_t start, uint64_t haddr)
>  {
> -void *aligned = (void *)(uintptr_t)(haddr & (-qemu_ram_pagesize(rb)));
> +void *aligned = (void *)QEMU_ALIGN_DOWN(haddr, qemu_ram_pagesize(rb));

Is uintptr_t still needed?  I thought it would generate a warning otherwise but
not sure.

Also, maybe ROUND_DOWN() is better?  QEMU_ALIGN_DOWN is the slow version for
arbitrary numbers.

-- 
Peter Xu




Re: [PATCH v4 8/9] migration/ram: Factor out populating pages readable in ram_block_populate_pages()

2021-09-02 Thread Peter Xu
On Thu, Sep 02, 2021 at 03:14:31PM +0200, David Hildenbrand wrote:
> Let's factor out prefaulting/populating to make further changes easier to
> review. While at it, use the actual page size of the ramblock, which
> defaults to qemu_real_host_page_size for anonymous memory.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  migration/ram.c | 21 -
>  1 file changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index e1c158dc92..de47650c90 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -1639,6 +1639,17 @@ out:
>  return ret;
>  }
>  
> +static inline void populate_range(RAMBlock *block, ram_addr_t offset,
> +  ram_addr_t size)
> +{
> +for (; offset < size; offset += block->page_size) {
> +char tmp = *((char *)block->host + offset);
> +
> +/* Don't optimize the read out */
> +asm volatile("" : "+r" (tmp));
> +}
> +}

If to make it a common function, make it populate_range_read()?

Just to identify from RW, as we'll fill the holes with zero pages only, not
doing page allocations yet, so not a complete "populate".

That'll be good enough for live snapshot as uffd-wp works for zero pages,
however I'm just afraid it may stop working for some new users of it when zero
pages won't suffice.

Maybe some comment would help too?

-- 
Peter Xu




Re: [PATCH] net: Add "info neighbors" command

2021-09-02 Thread Patrick Venture
On Thu, Sep 2, 2021 at 2:21 PM Doug Evans  wrote:

> This command dumps the ARP and NDP tables maintained within slirp.
> One use-case for it is showing the guest's IPv6 address(es).
>
> Signed-off-by: Doug Evans 
>
Reviewed-by: Patrick Venture 

> ---
>  hmp-commands-info.hx   | 15 +++
>  include/net/slirp.h|  1 +
>  net/slirp.c| 15 +++
>  tests/acceptance/info_neighbors.py | 69 ++
>  4 files changed, 100 insertions(+)
>  create mode 100644 tests/acceptance/info_neighbors.py
>
> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> index 27206ac049..386f09f163 100644
> --- a/hmp-commands-info.hx
> +++ b/hmp-commands-info.hx
> @@ -512,6 +512,21 @@ SRST
>  Show user network stack connection states.
>  ERST
>
> +#if defined(CONFIG_SLIRP)
> +{
> +.name   = "neighbors",
> +.args_type  = "",
> +.params = "",
> +.help   = "show the ARP and NDP tables",
> +.cmd= hmp_info_neighbors,
> +},
> +#endif
> +
> +SRST
> +  ``info neighbors``
> +Show the ARP and NDP tables.
> +ERST
> +
>  {
>  .name   = "migrate",
>  .args_type  = "",
> diff --git a/include/net/slirp.h b/include/net/slirp.h
> index bad3e1e241..b9ccfda1e7 100644
> --- a/include/net/slirp.h
> +++ b/include/net/slirp.h
> @@ -31,6 +31,7 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
>  void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);
>
>  void hmp_info_usernet(Monitor *mon, const QDict *qdict);
> +void hmp_info_neighbors(Monitor *mon, const QDict *qdict);
>
>  #endif
>
> diff --git a/net/slirp.c b/net/slirp.c
> index ad3a838e0b..29a4cd3fe1 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -1028,6 +1028,21 @@ void hmp_info_usernet(Monitor *mon, const QDict
> *qdict)
>  }
>  }
>
> +void hmp_info_neighbors(Monitor *mon, const QDict *qdict)
> +{
> +SlirpState *s;
> +
> +QTAILQ_FOREACH(s, _stacks, entry) {
> +int id;
> +bool got_hub_id = net_hub_id_for_client(>nc, ) == 0;
> +char *info = slirp_neighbor_info(s->slirp);
> +monitor_printf(mon, "Hub %d (%s):\n%s",
> +   got_hub_id ? id : -1,
> +   s->nc.name, info);
> +g_free(info);
> +}
> +}
> +
>  static void
>  net_init_slirp_configs(const StringList *fwd, int flags)
>  {
> diff --git a/tests/acceptance/info_neighbors.py
> b/tests/acceptance/info_neighbors.py
> new file mode 100644
> index 00..ff79ec3ff3
> --- /dev/null
> +++ b/tests/acceptance/info_neighbors.py
> @@ -0,0 +1,69 @@
> +# Test for the hmp command "info neighbors"
> +#
> +# Copyright 2021 Google LLC
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +
> +import re
> +
> +from avocado_qemu import LinuxTest
> +from avocado_qemu import Test
> +
> +VNET_HUB_HEADER = 'Hub -1 (vnet):'
> +NEIGHBOR_HEADER_REGEX = '^ *Table *MacAddr *IP Address$'
> +
> +def trim(text):
> +return " ".join(text.split())
> +
> +def hmc(test, cmd):
> +return test.vm.command('human-monitor-command', command_line=cmd)
> +
> +def get_neighbors(test):
> +output = hmc(test, 'info neighbors').splitlines()
> +if len(output) < 2:
> +test.fail("Insufficient output from 'info neighbors'")
> +test.assertEquals(output[0], VNET_HUB_HEADER)
> +test.assertTrue(re.fullmatch(NEIGHBOR_HEADER_REGEX, output[1]))
> +return output[2:]
> +
> +class InfoNeighborsNone(Test):
> +
> +def test_no_neighbors(self):
> +self.vm.add_args('-nodefaults',
> + '-netdev', 'user,id=vnet',
> + '-device', 'virtio-net,netdev=vnet')
> +self.vm.launch()
> +neighbors = get_neighbors(self)
> +self.assertEquals(len(neighbors), 0)
> +
> +class InfoNeighbors(LinuxTest):
> +
> +def test_neighbors(self):
> +"""
> +:avocado: tags=arch:x86_64
> +:avocado: tags=machine:pc
> +:avocado: tags=accel:kvm
> +"""
> +self.require_accelerator('kvm')
> +self.vm.add_args("-accel", "kvm")
> +self.vm.add_args('-nographic',
> + '-m', '1024')
> +self.launch_and_wait()
> +
> +# Ensure there's some packets to the guest and back.
> +self.ssh_command('pwd')
> +
> +# We should now be aware of the guest as a neighbor.
> +expected_ipv4_neighbor = 'ARP 52:54:00:12:34:56 10.0.2.15'
> +# The default ipv6 net is fec0. Both fe80 and fec0 can appear.
> +expected_ipv6_neighbors = [
> +'NDP 52:54:00:12:34:56 fe80::5054:ff:fe12:3456',
> +'NDP 52:54:00:12:34:56 fec0::5054:ff:fe12:3456'
> +]
> +neighbors = get_neighbors(self)
> +self.assertTrue(len(neighbors) >= 2 and len(neighbors) <= 3)
> +# IPv4 is output first.
> +

Re: [PATCH v5 2/2] memory: Have 'info mtree' remove duplicated Address Space information

2021-09-02 Thread Peter Xu
Hi, Phil,

On Thu, Sep 02, 2021 at 08:26:04AM +0200, Philippe Mathieu-Daudé wrote:
>   address-space shared 4 times:

I commented on the format of the output, I saw that it's switched back to the
v1.  Any reason?

Although I still think what I proposed looks better, I don't have a strong "no"
to this either.  Just want to know the motivations.

E.g., for a script parsing this output, it can easily skip and identify
duplications when scanned "address-space:" following another "address-space:".
Now it needs to understand two layouts, and that "N times" looks superfluous.

> - bcm2835-dma-memory
> - bcm2835-fb-memory
> - bcm2835-property-memory
> - dwc2
> - (prio 0, i/o): bcm2835-gpu
>   -3fff (prio 0, ram): alias 
> bcm2835-gpu-ram-alias[*] @ram -3fff
>   4000-7fff (prio 0, ram): alias 
> bcm2835-gpu-ram-alias[*] @ram -3fff
>   7e00-7eff (prio 1, i/o): alias 
> bcm2835-peripherals @bcm2835-peripherals -00ff
>   8000-bfff (prio 0, ram): alias 
> bcm2835-gpu-ram-alias[*] @ram -3fff
>   c000- (prio 0, ram): alias 
> bcm2835-gpu-ram-alias[*] @ram -3fff
> 
>   address-space: bcm2835-mbox-memory
> -008f (prio 0, i/o): bcm2835-mbox
>   0010-001f (prio 0, i/o): bcm2835-fb
>   0080-008f (prio 0, i/o): bcm2835-property

-- 
Peter Xu




Re: [PATCH v5 1/2] memory: Split mtree_info() as mtree_info_flatview() + mtree_info_as()

2021-09-02 Thread Peter Xu
On Thu, Sep 02, 2021 at 08:26:03AM +0200, Philippe Mathieu-Daudé wrote:
> While mtree_info() handles both ASes and flatviews cases,
> the two cases share basically no code. Split mtree_info()
> as mtree_info_flatview() + mtree_info_as() to simplify.
> 
> Suggested-by: Peter Maydell 
> Reviewed-by: David Hildenbrand 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Peter Xu 

-- 
Peter Xu




[PATCH] net: Add "info neighbors" command

2021-09-02 Thread Doug Evans
This command dumps the ARP and NDP tables maintained within slirp.
One use-case for it is showing the guest's IPv6 address(es).

Signed-off-by: Doug Evans 
---
 hmp-commands-info.hx   | 15 +++
 include/net/slirp.h|  1 +
 net/slirp.c| 15 +++
 tests/acceptance/info_neighbors.py | 69 ++
 4 files changed, 100 insertions(+)
 create mode 100644 tests/acceptance/info_neighbors.py

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 27206ac049..386f09f163 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -512,6 +512,21 @@ SRST
 Show user network stack connection states.
 ERST
 
+#if defined(CONFIG_SLIRP)
+{
+.name   = "neighbors",
+.args_type  = "",
+.params = "",
+.help   = "show the ARP and NDP tables",
+.cmd= hmp_info_neighbors,
+},
+#endif
+
+SRST
+  ``info neighbors``
+Show the ARP and NDP tables.
+ERST
+
 {
 .name   = "migrate",
 .args_type  = "",
diff --git a/include/net/slirp.h b/include/net/slirp.h
index bad3e1e241..b9ccfda1e7 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -31,6 +31,7 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
 void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);
 
 void hmp_info_usernet(Monitor *mon, const QDict *qdict);
+void hmp_info_neighbors(Monitor *mon, const QDict *qdict);
 
 #endif
 
diff --git a/net/slirp.c b/net/slirp.c
index ad3a838e0b..29a4cd3fe1 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -1028,6 +1028,21 @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
 }
 }
 
+void hmp_info_neighbors(Monitor *mon, const QDict *qdict)
+{
+SlirpState *s;
+
+QTAILQ_FOREACH(s, _stacks, entry) {
+int id;
+bool got_hub_id = net_hub_id_for_client(>nc, ) == 0;
+char *info = slirp_neighbor_info(s->slirp);
+monitor_printf(mon, "Hub %d (%s):\n%s",
+   got_hub_id ? id : -1,
+   s->nc.name, info);
+g_free(info);
+}
+}
+
 static void
 net_init_slirp_configs(const StringList *fwd, int flags)
 {
diff --git a/tests/acceptance/info_neighbors.py 
b/tests/acceptance/info_neighbors.py
new file mode 100644
index 00..ff79ec3ff3
--- /dev/null
+++ b/tests/acceptance/info_neighbors.py
@@ -0,0 +1,69 @@
+# Test for the hmp command "info neighbors"
+#
+# Copyright 2021 Google LLC
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+import re
+
+from avocado_qemu import LinuxTest
+from avocado_qemu import Test
+
+VNET_HUB_HEADER = 'Hub -1 (vnet):'
+NEIGHBOR_HEADER_REGEX = '^ *Table *MacAddr *IP Address$'
+
+def trim(text):
+return " ".join(text.split())
+
+def hmc(test, cmd):
+return test.vm.command('human-monitor-command', command_line=cmd)
+
+def get_neighbors(test):
+output = hmc(test, 'info neighbors').splitlines()
+if len(output) < 2:
+test.fail("Insufficient output from 'info neighbors'")
+test.assertEquals(output[0], VNET_HUB_HEADER)
+test.assertTrue(re.fullmatch(NEIGHBOR_HEADER_REGEX, output[1]))
+return output[2:]
+
+class InfoNeighborsNone(Test):
+
+def test_no_neighbors(self):
+self.vm.add_args('-nodefaults',
+ '-netdev', 'user,id=vnet',
+ '-device', 'virtio-net,netdev=vnet')
+self.vm.launch()
+neighbors = get_neighbors(self)
+self.assertEquals(len(neighbors), 0)
+
+class InfoNeighbors(LinuxTest):
+
+def test_neighbors(self):
+"""
+:avocado: tags=arch:x86_64
+:avocado: tags=machine:pc
+:avocado: tags=accel:kvm
+"""
+self.require_accelerator('kvm')
+self.vm.add_args("-accel", "kvm")
+self.vm.add_args('-nographic',
+ '-m', '1024')
+self.launch_and_wait()
+
+# Ensure there's some packets to the guest and back.
+self.ssh_command('pwd')
+
+# We should now be aware of the guest as a neighbor.
+expected_ipv4_neighbor = 'ARP 52:54:00:12:34:56 10.0.2.15'
+# The default ipv6 net is fec0. Both fe80 and fec0 can appear.
+expected_ipv6_neighbors = [
+'NDP 52:54:00:12:34:56 fe80::5054:ff:fe12:3456',
+'NDP 52:54:00:12:34:56 fec0::5054:ff:fe12:3456'
+]
+neighbors = get_neighbors(self)
+self.assertTrue(len(neighbors) >= 2 and len(neighbors) <= 3)
+# IPv4 is output first.
+self.assertEquals(trim(neighbors[0]), expected_ipv4_neighbor)
+for neighbor in neighbors[1:]:
+self.assertTrue(trim(neighbor) in expected_ipv6_neighbors)
-- 
2.33.0.153.gba50c8fa24-goog




RE: [PATCH v2 04/19] host-utils: add 128-bit quotient support to divu128/divs128

2021-09-02 Thread Luis Fernando Fujita Pires
From: Richard Henderson 
> Hmm.  I'll note that we have a better divmod primitive in tree, but we aren't
> using it
> here: udiv_qrnnd in include/fpu/softfloat-macros.h.

Good to know! I'll change to a (much simpler) implementation using udiv_qrnnd.
Any pointers on what would be a good place to put udiv_qrnnd, so it can be used 
by softloat.c and host-utils.c? Would host-utils.h be ok?

> Given that none of the existing uses require the high part, should we be 
> creating
> a new interface?  The bug you highlight wrt truncation could be fixed 
> separately.

Although it does fix the bug, the motivation for the new interface is not 
really that bug. I wanted a 128-bit division that could return quotients larger 
than 64-bit, so I could use it in decNumberFrom[U]Int128, introduced in the 
next commit.

> > -void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
> > +void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem, int64_t
> > +divisor)
> >   {
> > -int sgn_dvdnd = *phigh < 0;
> > -int sgn_divsr = divisor < 0;
> > +int neg_quotient = 0, neg_remainder = 0;
> 
> You might as well use bool.

Sure, will do.

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


RE: [PATCH v2 03/19] host-utils: move checks out of divu128/divs128

2021-09-02 Thread Luis Fernando Fujita Pires
From: Richard Henderson 
> > -static inline int divs128(int64_t *plow, int64_t *phigh, int64_t
> > divisor)
> > +static inline void divs128(int64_t *plow, int64_t *phigh, int64_t
> > +divisor)
> >   {
> > -if (divisor == 0) {
> > -return 1;
> > -} else {
> > -__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
> > -__int128_t result = dividend / divisor;
> > -*plow = result;
> > -*phigh = dividend % divisor;
> > -return result != *plow;
> > -}
> > +__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
>
> This is incorrect, before and after: *plow must be zero-extended here.

This will no longer be a problem after patch 4, when plow is changed to be 
uint64_t*, but I can fix it here, too.

> > @@ -97,13 +101,11 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t
> divisor)
> >   uint64_t carry = 0;
> >
> >   if (divisor == 0) {
> > -return 1;
> > +/* intentionally cause a division by 0 */
> > +*plow = 1 / divisor;
> >   } else if (dhi == 0) {
> >   *plow  = dlo / divisor;
> >   *phigh = dlo % divisor;
> 
> Let's not do two undefined things and leave *phigh uninitialized (e.g. riscv 
> host,
> where div-by-zero does not trap).  Just fold the div-by-zero case into the 
> dhi == 0
> case.

Will do.

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


Re: [PATCH 24/24] user: Remove cpu_get_pic_interrupt() stubs

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:19 AM Philippe Mathieu-Daudé 
wrote:

> cpu_get_pic_interrupt() is now unreachable from user-mode,
> delete the unnecessary stubs.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/i386/cpu.h | 2 +-
>  bsd-user/main.c   | 7 ---
>  linux-user/main.c | 7 ---
>  3 files changed, 1 insertion(+), 15 deletions(-)
>

Reviewed-by: Warner Losh 


> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index c241bc183d2..c7cc65e92d5 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1832,9 +1832,9 @@ int x86_cpu_gdb_write_register(CPUState *cpu,
> uint8_t *buf, int reg);
>  void x86_cpu_list(void);
>  int cpu_x86_support_mca_broadcast(CPUX86State *env);
>
> +#ifndef CONFIG_USER_ONLY
>  int cpu_get_pic_interrupt(CPUX86State *s);
>
> -#ifndef CONFIG_USER_ONLY
>  /* MSDOS compatibility mode FPU exception support */
>  void x86_register_ferr_irq(qemu_irq irq);
>  void fpu_check_raise_ferr_irq(CPUX86State *s);
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index fe66204b6b7..e358c38c353 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -66,13 +66,6 @@ void gemu_log(const char *fmt, ...)
>  va_end(ap);
>  }
>
> -#if defined(TARGET_I386)
> -int cpu_get_pic_interrupt(CPUX86State *env)
> -{
> -return -1;
> -}
> -#endif
> -
>  void fork_start(void)
>  {
>  }
>

Love it, but either you or I will have to rebase based on which of us lands
in the tree first :).
For me, the rebase will be easy though.


> diff --git a/linux-user/main.c b/linux-user/main.c
> index 37ed50d98e2..f5c0a82427b 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -120,13 +120,6 @@ const char *qemu_uname_release;
> by remapping the process stack directly at the right place */
>  unsigned long guest_stack_size = 8 * 1024 * 1024UL;
>
> -#if defined(TARGET_I386)
> -int cpu_get_pic_interrupt(CPUX86State *env)
> -{
> -return -1;
> -}
> -#endif
> -
>  /***/
>  /* Helper routines for implementing atomic operations.  */
>
> --
> 2.31.1
>
>


Re: [PATCH 22/24] target/xtensa: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:19 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/xtensa/cpu.h| 4 ++--
>  target/xtensa/cpu.c| 2 +-
>  target/xtensa/exc_helper.c | 7 ++-
>  3 files changed, 5 insertions(+), 8 deletions(-)
>

Reviewed-by: Warner Losh 



> diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
> index 1e0cb1535ca..cbb720e7cca 100644
> --- a/target/xtensa/cpu.h
> +++ b/target/xtensa/cpu.h
> @@ -566,14 +566,14 @@ struct XtensaCPU {
>  bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>   MMUAccessType access_type, int mmu_idx,
>   bool probe, uintptr_t retaddr);
> +#ifndef CONFIG_USER_ONLY
>  void xtensa_cpu_do_interrupt(CPUState *cpu);
>  bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
> -#ifndef CONFIG_USER_ONLY
>  void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
> vaddr addr,
>unsigned size, MMUAccessType
> access_type,
>int mmu_idx, MemTxAttrs attrs,
>MemTxResult response, uintptr_t
> retaddr);
> -#endif /* !CONFIG_USER_ONLY */
> +#endif
>  void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  void xtensa_count_regs(const XtensaConfig *config,
> diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
> index 58ec3a08622..c1cbd03595e 100644
> --- a/target/xtensa/cpu.c
> +++ b/target/xtensa/cpu.c
> @@ -192,11 +192,11 @@ static const struct SysemuCPUOps xtensa_sysemu_ops =
> {
>
>  static const struct TCGCPUOps xtensa_tcg_ops = {
>  .initialize = xtensa_translate_init,
> -.cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
>  .tlb_fill = xtensa_cpu_tlb_fill,
>  .debug_excp_handler = xtensa_breakpoint_handler,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
>  .do_interrupt = xtensa_cpu_do_interrupt,
>  .do_transaction_failed = xtensa_cpu_do_transaction_failed,
>  .do_unaligned_access = xtensa_cpu_do_unaligned_access,
> diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
> index 10e75ab070d..9bc7f50d355 100644
> --- a/target/xtensa/exc_helper.c
> +++ b/target/xtensa/exc_helper.c
> @@ -255,11 +255,6 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>  }
>  check_interrupts(env);
>  }
> -#else
> -void xtensa_cpu_do_interrupt(CPUState *cs)
> -{
> -}
> -#endif
>
>  bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -270,3 +265,5 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  }
>  return false;
>  }
> +
> +#endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 18/24] target/riscv: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/riscv/cpu.h| 2 +-
>  target/riscv/cpu.c| 2 +-
>  target/riscv/cpu_helper.c | 5 -
>  3 files changed, 2 insertions(+), 7 deletions(-)
>
> Reviewed-by: Warner Losh 



> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index bf1c899c00b..e735e53e26c 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -334,7 +334,6 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction
> f, CPUState *cs,
> int cpuid, void *opaque);
>  int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
>  int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> -bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
>  bool riscv_cpu_fp_enabled(CPURISCVState *env);
>  bool riscv_cpu_virt_enabled(CPURISCVState *env);
>  void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
> @@ -362,6 +361,7 @@ void riscv_cpu_list(void);
>  #define cpu_mmu_index riscv_cpu_mmu_index
>
>  #ifndef CONFIG_USER_ONLY
> +bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
>  void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
>  int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
>  uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t
> value);
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1a2b03d579c..13575c14085 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -644,10 +644,10 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
>  static const struct TCGCPUOps riscv_tcg_ops = {
>  .initialize = riscv_translate_init,
>  .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
>  .tlb_fill = riscv_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
>  .do_interrupt = riscv_cpu_do_interrupt,
>  .do_transaction_failed = riscv_cpu_do_transaction_failed,
>  .do_unaligned_access = riscv_cpu_do_unaligned_access,
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 968cb8046f4..701858d670c 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -75,11 +75,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState
> *env)
>  return RISCV_EXCP_NONE; /* indicates no pending interrupt */
>  }
>  }
> -#endif
>
>  bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> -#if !defined(CONFIG_USER_ONLY)
>  if (interrupt_request & CPU_INTERRUPT_HARD) {
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  CPURISCVState *env = >env;
> @@ -90,12 +88,9 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return true;
>  }
>  }
> -#endif
>  return false;
>  }
>
> -#if !defined(CONFIG_USER_ONLY)
> -
>  /* Return true is floating point support is currently enabled */
>  bool riscv_cpu_fp_enabled(CPURISCVState *env)
>  {
> --
> 2.31.1
>
>


Re: [PATCH 21/24] target/rx: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:19 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/rx/cpu.h| 2 ++
>  target/rx/cpu.c| 2 +-
>  target/rx/helper.c | 4 
>  3 files changed, 7 insertions(+), 1 deletion(-)
>

Reviewed-by: Warner Losh 



> diff --git a/target/rx/cpu.h b/target/rx/cpu.h
> index 0b4b998c7be..faa3606f52f 100644
> --- a/target/rx/cpu.h
> +++ b/target/rx/cpu.h
> @@ -124,8 +124,10 @@ typedef RXCPU ArchCPU;
>  #define CPU_RESOLVING_TYPE TYPE_RX_CPU
>
>  const char *rx_crname(uint8_t cr);
> +#ifndef CONFIG_USER_ONLY
>  void rx_cpu_do_interrupt(CPUState *cpu);
>  bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>  void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
>  int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target/rx/cpu.c b/target/rx/cpu.c
> index 96cc96e514f..25a4aa2976d 100644
> --- a/target/rx/cpu.c
> +++ b/target/rx/cpu.c
> @@ -186,10 +186,10 @@ static const struct SysemuCPUOps rx_sysemu_ops = {
>  static const struct TCGCPUOps rx_tcg_ops = {
>  .initialize = rx_translate_init,
>  .synchronize_from_tb = rx_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = rx_cpu_exec_interrupt,
>  .tlb_fill = rx_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = rx_cpu_exec_interrupt,
>  .do_interrupt = rx_cpu_do_interrupt,
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/rx/helper.c b/target/rx/helper.c
> index db6b07e3890..f34945e7e2c 100644
> --- a/target/rx/helper.c
> +++ b/target/rx/helper.c
> @@ -40,6 +40,8 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw,
> int rte)
>  env->psw_c = FIELD_EX32(psw, PSW, C);
>  }
>
> +#ifndef CONFIG_USER_ONLY
> +
>  #define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
>  void rx_cpu_do_interrupt(CPUState *cs)
>  {
> @@ -142,6 +144,8 @@ bool rx_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  hwaddr rx_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>  {
>  return addr;
> --
> 2.31.1
>
>


Re: [PATCH 17/24] target/ppc: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/ppc/cpu.h |  4 ++--
>  target/ppc/cpu_init.c|  2 +-
>  target/ppc/excp_helper.c | 21 +++--
>  3 files changed, 6 insertions(+), 21 deletions(-)
>
> Reviewed-by: Warner Losh 



> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 500205229c0..362e7c4c5c7 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1254,8 +1254,6 @@ DECLARE_OBJ_CHECKERS(PPCVirtualHypervisor,
> PPCVirtualHypervisorClass,
>   PPC_VIRTUAL_HYPERVISOR, TYPE_PPC_VIRTUAL_HYPERVISOR)
>  #endif /* CONFIG_USER_ONLY */
>
> -void ppc_cpu_do_interrupt(CPUState *cpu);
> -bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
> @@ -1271,6 +1269,8 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction
> f, CPUState *cs,
>  int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
> +void ppc_cpu_do_interrupt(CPUState *cpu);
> +bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
>  extern const VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index ad7abc6041a..6aad01d1d3a 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -9014,10 +9014,10 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
>
>  static const struct TCGCPUOps ppc_tcg_ops = {
>.initialize = ppc_translate_init,
> -  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
>.tlb_fill = ppc_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
>.do_interrupt = ppc_cpu_do_interrupt,
>.cpu_exec_enter = ppc_cpu_exec_enter,
>.cpu_exec_exit = ppc_cpu_exec_exit,
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 7b6ac16eef7..d7e32ee107e 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -40,24 +40,8 @@
>
>
>  
> /*/
>  /* Exception processing */
> -#if defined(CONFIG_USER_ONLY)
> -void ppc_cpu_do_interrupt(CPUState *cs)
> -{
> -PowerPCCPU *cpu = POWERPC_CPU(cs);
> -CPUPPCState *env = >env;
> +#if !defined(CONFIG_USER_ONLY)
>
> -cs->exception_index = POWERPC_EXCP_NONE;
> -env->error_code = 0;
> -}
> -
> -static void ppc_hw_interrupt(CPUPPCState *env)
> -{
> -CPUState *cs = env_cpu(env);
> -
> -cs->exception_index = POWERPC_EXCP_NONE;
> -env->error_code = 0;
> -}
> -#else /* defined(CONFIG_USER_ONLY) */
>  static inline void dump_syscall(CPUPPCState *env)
>  {
>  qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
> @@ -1113,7 +1097,6 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs,
> target_ulong vector)
>
>  powerpc_set_excp_state(cpu, vector, msr);
>  }
> -#endif /* !CONFIG_USER_ONLY */
>
>  bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -1130,6 +1113,8 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  #if defined(DEBUG_OP)
>  static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
>  {
> --
> 2.31.1
>
>


Re: [PATCH 20/24] target/sparc: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:19 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/sparc/cpu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> Reviewed-by: Warner Losh 



> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index da6b30ec747..5a8a4ce7506 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -77,6 +77,7 @@ static void sparc_cpu_reset(DeviceState *dev)
>  env->cache_control = 0;
>  }
>
> +#ifndef CONFIG_USER_ONLY
>  static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  if (interrupt_request & CPU_INTERRUPT_HARD) {
> @@ -96,6 +97,7 @@ static bool sparc_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  }
>  return false;
>  }
> +#endif /* !CONFIG_USER_ONLY */
>
>  static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info
> *info)
>  {
> @@ -863,10 +865,10 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
>  static const struct TCGCPUOps sparc_tcg_ops = {
>  .initialize = sparc_tcg_init,
>  .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = sparc_cpu_exec_interrupt,
>  .tlb_fill = sparc_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = sparc_cpu_exec_interrupt,
>  .do_interrupt = sparc_cpu_do_interrupt,
>  .do_transaction_failed = sparc_cpu_do_transaction_failed,
>  .do_unaligned_access = sparc_cpu_do_unaligned_access,
> --
> 2.31.1
>
>


Re: [PATCH 15/24] target/nios2: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/nios2/cpu.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>

Reviewed-by: Warner Losh 



> diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
> index 5e37defef80..947bb09bc1e 100644
> --- a/target/nios2/cpu.c
> +++ b/target/nios2/cpu.c
> @@ -127,6 +127,7 @@ static void nios2_cpu_realizefn(DeviceState *dev,
> Error **errp)
>  ncc->parent_realize(dev, errp);
>  }
>
> +#ifndef CONFIG_USER_ONLY
>  static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  Nios2CPU *cpu = NIOS2_CPU(cs);
> @@ -140,7 +141,7 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  }
>  return false;
>  }
> -
> +#endif /* !CONFIG_USER_ONLY */
>
>  static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info
> *info)
>  {
> @@ -219,10 +220,10 @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
>
>  static const struct TCGCPUOps nios2_tcg_ops = {
>  .initialize = nios2_tcg_init,
> -.cpu_exec_interrupt = nios2_cpu_exec_interrupt,
>  .tlb_fill = nios2_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = nios2_cpu_exec_interrupt,
>  .do_interrupt = nios2_cpu_do_interrupt,
>  .do_unaligned_access = nios2_cpu_do_unaligned_access,
>  #endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 19/24] target/sh4: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:19 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/sh4/cpu.h| 4 ++--
>  target/sh4/cpu.c| 2 +-
>  target/sh4/helper.c | 9 ++---
>  3 files changed, 5 insertions(+), 10 deletions(-)
>
> Reviewed-by: Warner Losh 



> diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
> index 01c43440822..017a7702140 100644
> --- a/target/sh4/cpu.h
> +++ b/target/sh4/cpu.h
> @@ -204,8 +204,6 @@ struct SuperHCPU {
>  };
>
>
> -void superh_cpu_do_interrupt(CPUState *cpu);
> -bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
> @@ -223,6 +221,8 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address,
> int size,
>
>  void sh4_cpu_list(void);
>  #if !defined(CONFIG_USER_ONLY)
> +void superh_cpu_do_interrupt(CPUState *cpu);
> +bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void cpu_sh4_invalidate_tlb(CPUSH4State *s);
>  uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
> hwaddr addr);
> diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
> index 83269229421..2047742d03c 100644
> --- a/target/sh4/cpu.c
> +++ b/target/sh4/cpu.c
> @@ -236,10 +236,10 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
>  static const struct TCGCPUOps superh_tcg_ops = {
>  .initialize = sh4_translate_init,
>  .synchronize_from_tb = superh_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = superh_cpu_exec_interrupt,
>  .tlb_fill = superh_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = superh_cpu_exec_interrupt,
>  .do_interrupt = superh_cpu_do_interrupt,
>  .do_unaligned_access = superh_cpu_do_unaligned_access,
>  .io_recompile_replay_branch = superh_io_recompile_replay_branch,
> diff --git a/target/sh4/helper.c b/target/sh4/helper.c
> index 2d622081e85..53cb9c3b631 100644
> --- a/target/sh4/helper.c
> +++ b/target/sh4/helper.c
> @@ -45,11 +45,6 @@
>
>  #if defined(CONFIG_USER_ONLY)
>
> -void superh_cpu_do_interrupt(CPUState *cs)
> -{
> -cs->exception_index = -1;
> -}
> -
>  int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
>  {
>  /* For user mode, only U0 area is cacheable. */
> @@ -784,8 +779,6 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong
> addr)
>  return 0;
>  }
>
> -#endif
> -
>  bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  if (interrupt_request & CPU_INTERRUPT_HARD) {
> @@ -803,6 +796,8 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>   MMUAccessType access_type, int mmu_idx,
>   bool probe, uintptr_t retaddr)
> --
> 2.31.1
>
>


Re: [PATCH 14/24] target/mips: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/tcg/tcg-internal.h  |  5 +++--
>  target/mips/cpu.c   |  2 +-
>  target/mips/tcg/exception.c | 18 --
>  target/mips/tcg/sysemu/tlb_helper.c | 18 ++
>  target/mips/tcg/user/tlb_helper.c   |  5 -
>  5 files changed, 22 insertions(+), 26 deletions(-)
>
> Reviewed-by: Warner Losh 


> diff --git a/target/mips/tcg/tcg-internal.h
> b/target/mips/tcg/tcg-internal.h
> index 81b14eb219e..c7a77ddccdd 100644
> --- a/target/mips/tcg/tcg-internal.h
> +++ b/target/mips/tcg/tcg-internal.h
> @@ -18,8 +18,6 @@
>  void mips_tcg_init(void);
>
>  void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock
> *tb);
> -void mips_cpu_do_interrupt(CPUState *cpu);
> -bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> MMUAccessType access_type, int mmu_idx,
> bool probe, uintptr_t retaddr);
> @@ -41,6 +39,9 @@ static inline void QEMU_NORETURN
> do_raise_exception(CPUMIPSState *env,
>
>  #if !defined(CONFIG_USER_ONLY)
>
> +void mips_cpu_do_interrupt(CPUState *cpu);
> +bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +
>  void mmu_init(CPUMIPSState *env, const mips_def_t *def);
>
>  void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t
> *pagemask);
> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
> index d426918291a..00e0c55d0e4 100644
> --- a/target/mips/cpu.c
> +++ b/target/mips/cpu.c
> @@ -539,10 +539,10 @@ static const struct SysemuCPUOps mips_sysemu_ops = {
>  static const struct TCGCPUOps mips_tcg_ops = {
>  .initialize = mips_tcg_init,
>  .synchronize_from_tb = mips_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = mips_cpu_exec_interrupt,
>  .tlb_fill = mips_cpu_tlb_fill,
>
>  #if !defined(CONFIG_USER_ONLY)
> +.cpu_exec_interrupt = mips_cpu_exec_interrupt,
>  .do_interrupt = mips_cpu_do_interrupt,
>  .do_transaction_failed = mips_cpu_do_transaction_failed,
>  .do_unaligned_access = mips_cpu_do_unaligned_access,
> diff --git a/target/mips/tcg/exception.c b/target/mips/tcg/exception.c
> index 4fb8b00711d..7b3026b105b 100644
> --- a/target/mips/tcg/exception.c
> +++ b/target/mips/tcg/exception.c
> @@ -86,24 +86,6 @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const
> TranslationBlock *tb)
>  env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
>  }
>
> -bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> -{
> -if (interrupt_request & CPU_INTERRUPT_HARD) {
> -MIPSCPU *cpu = MIPS_CPU(cs);
> -CPUMIPSState *env = >env;
> -
> -if (cpu_mips_hw_interrupts_enabled(env) &&
> -cpu_mips_hw_interrupts_pending(env)) {
> -/* Raise it */
> -cs->exception_index = EXCP_EXT_INTERRUPT;
> -env->error_code = 0;
> -mips_cpu_do_interrupt(cs);
> -return true;
> -}
> -}
> -return false;
> -}
> -
>  static const char * const excp_names[EXCP_LAST + 1] = {
>  [EXCP_RESET] = "reset",
>  [EXCP_SRESET] = "soft reset",
> diff --git a/target/mips/tcg/sysemu/tlb_helper.c
> b/target/mips/tcg/sysemu/tlb_helper.c
> index a150a014ec1..73254d19298 100644
> --- a/target/mips/tcg/sysemu/tlb_helper.c
> +++ b/target/mips/tcg/sysemu/tlb_helper.c
> @@ -1339,6 +1339,24 @@ void mips_cpu_do_interrupt(CPUState *cs)
>  cs->exception_index = EXCP_NONE;
>  }
>
> +bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> +{
> +if (interrupt_request & CPU_INTERRUPT_HARD) {
> +MIPSCPU *cpu = MIPS_CPU(cs);
> +CPUMIPSState *env = >env;
> +
> +if (cpu_mips_hw_interrupts_enabled(env) &&
> +cpu_mips_hw_interrupts_pending(env)) {
> +/* Raise it */
> +cs->exception_index = EXCP_EXT_INTERRUPT;
> +env->error_code = 0;
> +mips_cpu_do_interrupt(cs);
> +return true;
> +}
> +}
> +return false;
> +}
> +
>  void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
>  {
>  CPUState *cs = env_cpu(env);
> diff --git a/target/mips/tcg/user/tlb_helper.c
> b/target/mips/tcg/user/tlb_helper.c
> index b835144b820..210c6d529ef 100644
> --- a/target/mips/tcg/user/tlb_helper.c
> +++ b/target/mips/tcg/user/tlb_helper.c
> @@ -57,8 +57,3 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int
> size,
>  raise_mmu_exception(env, address, access_type);
>  do_raise_exception_err(env, cs->exception_index, env->error_code,
> retaddr);
>  }
> -
> -void mips_cpu_do_interrupt(CPUState *cs)
> -{
> -cs->exception_index = EXCP_NONE;
> -}
> --
> 2.31.1
>
>


Re: [PATCH 16/24] target/openrisc: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/openrisc/cpu.h   | 5 +++--
>  target/openrisc/cpu.c   | 2 +-
>  target/openrisc/interrupt.c | 2 --
>  target/openrisc/meson.build | 6 --
>  4 files changed, 8 insertions(+), 7 deletions(-)
>

I'm not 100% sure about the build changes because my meson fu is weak, but
they seem right given the rest.

Reviewed-by: Warner Losh 


> diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
> index 82cbaeb4f84..be6df81a810 100644
> --- a/target/openrisc/cpu.h
> +++ b/target/openrisc/cpu.h
> @@ -312,8 +312,6 @@ struct OpenRISCCPU {
>
>
>  void cpu_openrisc_list(void);
> -void openrisc_cpu_do_interrupt(CPUState *cpu);
> -bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int
> reg);
> @@ -331,6 +329,9 @@ int print_insn_or1k(bfd_vma addr, disassemble_info
> *info);
>  #ifndef CONFIG_USER_ONLY
>  extern const VMStateDescription vmstate_openrisc_cpu;
>
> +void openrisc_cpu_do_interrupt(CPUState *cpu);
> +bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +
>  /* hw/openrisc_pic.c */
>  void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
>
> diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
> index bd34e429ecb..27cb04152f9 100644
> --- a/target/openrisc/cpu.c
> +++ b/target/openrisc/cpu.c
> @@ -186,10 +186,10 @@ static const struct SysemuCPUOps openrisc_sysemu_ops
> = {
>
>  static const struct TCGCPUOps openrisc_tcg_ops = {
>  .initialize = openrisc_translate_init,
> -.cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
>  .tlb_fill = openrisc_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
>  .do_interrupt = openrisc_cpu_do_interrupt,
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
> index 3eab771dcda..19223e3f25b 100644
> --- a/target/openrisc/interrupt.c
> +++ b/target/openrisc/interrupt.c
> @@ -28,7 +28,6 @@
>
>  void openrisc_cpu_do_interrupt(CPUState *cs)
>  {
> -#ifndef CONFIG_USER_ONLY
>  OpenRISCCPU *cpu = OPENRISC_CPU(cs);
>  CPUOpenRISCState *env = >env;
>  int exception = cs->exception_index;
> @@ -96,7 +95,6 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
>  } else {
>  cpu_abort(cs, "Unhandled exception 0x%x\n", exception);
>  }
> -#endif
>
>  cs->exception_index = -1;
>  }
> diff --git a/target/openrisc/meson.build b/target/openrisc/meson.build
> index 9774a583065..e445dec4a00 100644
> --- a/target/openrisc/meson.build
> +++ b/target/openrisc/meson.build
> @@ -9,7 +9,6 @@
>'exception_helper.c',
>'fpu_helper.c',
>'gdbstub.c',
> -  'interrupt.c',
>'interrupt_helper.c',
>'mmu.c',
>'sys_helper.c',
> @@ -17,7 +16,10 @@
>  ))
>
>  openrisc_softmmu_ss = ss.source_set()
> -openrisc_softmmu_ss.add(files('machine.c'))
> +openrisc_softmmu_ss.add(files(
> +  'interrupt.c',
> +  'machine.c',
> +))
>
>  target_arch += {'openrisc': openrisc_ss}
>  target_softmmu_arch += {'openrisc': openrisc_softmmu_ss}
> --
> 2.31.1
>
>


Re: [PATCH 13/24] target/microblaze: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/microblaze/cpu.h|  2 ++
>  target/microblaze/cpu.c|  2 +-
>  target/microblaze/helper.c | 13 ++---
>  3 files changed, 5 insertions(+), 12 deletions(-)
>
>
Reviewed-by: Warner Losh 



> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index e4bba8a7551..40401c33b72 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -355,8 +355,10 @@ struct MicroBlazeCPU {
>  };
>
>
> +#ifndef CONFIG_USER_ONLY
>  void mb_cpu_do_interrupt(CPUState *cs);
>  bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>  void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
>  MMUAccessType access_type,
>  int mmu_idx, uintptr_t retaddr);
> diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
> index 72d8f2a0daa..15db277925f 100644
> --- a/target/microblaze/cpu.c
> +++ b/target/microblaze/cpu.c
> @@ -365,10 +365,10 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
>  static const struct TCGCPUOps mb_tcg_ops = {
>  .initialize = mb_tcg_init,
>  .synchronize_from_tb = mb_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = mb_cpu_exec_interrupt,
>  .tlb_fill = mb_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = mb_cpu_exec_interrupt,
>  .do_interrupt = mb_cpu_do_interrupt,
>  .do_transaction_failed = mb_cpu_transaction_failed,
>  .do_unaligned_access = mb_cpu_do_unaligned_access,
> diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
> index 20dbd673136..dd2aecd1d58 100644
> --- a/target/microblaze/helper.c
> +++ b/target/microblaze/helper.c
> @@ -26,16 +26,6 @@
>
>  #if defined(CONFIG_USER_ONLY)
>
> -void mb_cpu_do_interrupt(CPUState *cs)
> -{
> -MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
> -CPUMBState *env = >env;
> -
> -cs->exception_index = -1;
> -env->res_addr = RES_ADDR_NONE;
> -env->regs[14] = env->pc;
> -}
> -
>  bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>   MMUAccessType access_type, int mmu_idx,
>   bool probe, uintptr_t retaddr)
> @@ -271,7 +261,6 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs,
> vaddr addr,
>
>  return paddr;
>  }
> -#endif
>
>  bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -289,6 +278,8 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
>  MMUAccessType access_type,
>  int mmu_idx, uintptr_t retaddr)
> --
> 2.31.1
>
>


Re: [PATCH] hw/arm: Add support for kudo-bmc board.

2021-09-02 Thread Patrick Venture
On Thu, Sep 2, 2021 at 12:01 PM Chris Rauer  wrote:

> kudo-bmc is a board supported by OpenBMC.
> https://github.com/openbmc/openbmc/tree/master/meta-fii/meta-kudo
>
> Tested: Booted kudo firmware.
> Signed-off-by: Chris Rauer 
>
Reviewed-by: Patrick Venture 

> ---
>  docs/system/arm/nuvoton.rst |  1 +
>  hw/arm/npcm7xx_boards.c | 34 ++
>  2 files changed, 35 insertions(+)
>
> diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
> index 69f57c2886..adf497e679 100644
> --- a/docs/system/arm/nuvoton.rst
> +++ b/docs/system/arm/nuvoton.rst
> @@ -20,6 +20,7 @@ Hyperscale applications. The following machines are
> based on this chip :
>
>  - ``quanta-gbs-bmc``Quanta GBS server BMC
>  - ``quanta-gsj``Quanta GSJ server BMC
> +- ``kudo-bmc``  Fii USA Kudo server BMC
>
>  There are also two more SoCs, NPCM710 and NPCM705, which are single-core
>  variants of NPCM750 and NPCM730, respectively. These are currently not
> diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> index e5a3243995..c80f442adb 100644
> --- a/hw/arm/npcm7xx_boards.c
> +++ b/hw/arm/npcm7xx_boards.c
> @@ -31,6 +31,7 @@
>  #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
>  #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
>  #define QUANTA_GBS_POWER_ON_STRAPS 0x17ff
> +#define KUDO_BMC_POWER_ON_STRAPS 0x1fff
>
>  static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
>
> @@ -357,6 +358,23 @@ static void quanta_gbs_init(MachineState *machine)
>  npcm7xx_load_kernel(machine, soc);
>  }
>
> +static void kudo_bmc_init(MachineState *machine)
> +{
> +NPCM7xxState *soc;
> +
> +soc = npcm7xx_create_soc(machine, KUDO_BMC_POWER_ON_STRAPS);
> +npcm7xx_connect_dram(soc, machine->ram);
> +qdev_realize(DEVICE(soc), NULL, _fatal);
> +
> +npcm7xx_load_bootrom(machine, soc);
> +npcm7xx_connect_flash(>fiu[0], 0, "mx66u51235f",
> +  drive_get(IF_MTD, 0, 0));
> +npcm7xx_connect_flash(>fiu[1], 0, "mx66u51235f",
> +  drive_get(IF_MTD, 3, 0));
> +
> +npcm7xx_load_kernel(machine, soc);
> +}
> +
>  static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char
> *type)
>  {
>  NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
> @@ -417,6 +435,18 @@ static void gbs_bmc_machine_class_init(ObjectClass
> *oc, void *data)
>  mc->default_ram_size = 1 * GiB;
>  }
>
> +static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
> +{
> +NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
> +
> +mc->desc = "Kudo BMC (Cortex A9)";
> +mc->init = kudo_bmc_init;
> +mc->default_ram_size = 1 * GiB;
> +};
> +
>  static const TypeInfo npcm7xx_machine_types[] = {
>  {
>  .name   = TYPE_NPCM7XX_MACHINE,
> @@ -437,6 +467,10 @@ static const TypeInfo npcm7xx_machine_types[] = {
>  .name   = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
>  .parent = TYPE_NPCM7XX_MACHINE,
>  .class_init = gbs_bmc_machine_class_init,
> +}, {
> +.name   = MACHINE_TYPE_NAME("kudo-bmc"),
> +.parent = TYPE_NPCM7XX_MACHINE,
> +.class_init = kudo_bmc_machine_class_init,
>  },
>  };
>
> --
> 2.33.0.153.gba50c8fa24-goog
>
>
>


Re: [PATCH 11/24] target/i386: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/i386/tcg/helper-tcg.h |  2 ++
>  target/i386/tcg/seg_helper.c | 10 ++
>  target/i386/tcg/tcg-cpu.c|  2 +-
>  3 files changed, 5 insertions(+), 9 deletions(-)
>

Reviewed-by: Warner Losh 



> diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
> index 2510cc244e9..60ca09e95eb 100644
> --- a/target/i386/tcg/helper-tcg.h
> +++ b/target/i386/tcg/helper-tcg.h
> @@ -38,7 +38,9 @@ QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS >
> TARGET_PHYS_ADDR_SPACE_BITS);
>   * @cpu: vCPU the interrupt is to be handled by.
>   */
>  void x86_cpu_do_interrupt(CPUState *cpu);
> +#ifndef CONFIG_USER_ONLY
>  bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif
>
>  /* helper.c */
>  bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
> index dee7bef68c6..13c6e6ee62e 100644
> --- a/target/i386/tcg/seg_helper.c
> +++ b/target/i386/tcg/seg_helper.c
> @@ -1110,6 +1110,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int
> intno, int is_hw)
>  do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
>  }
>
> +#ifndef CONFIG_USER_ONLY
>  bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  X86CPU *cpu = X86_CPU(cs);
> @@ -1125,23 +1126,17 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>   * This is required to make icount-driven execution deterministic.
>   */
>  switch (interrupt_request) {
> -#if !defined(CONFIG_USER_ONLY)
>  case CPU_INTERRUPT_POLL:
>  cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
>  apic_poll_irq(cpu->apic_state);
>  break;
> -#endif
>  case CPU_INTERRUPT_SIPI:
>  do_cpu_sipi(cpu);
>  break;
>  case CPU_INTERRUPT_SMI:
>  cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0);
>  cs->interrupt_request &= ~CPU_INTERRUPT_SMI;
> -#ifdef CONFIG_USER_ONLY
> -cpu_abort(CPU(cpu), "SMI interrupt: cannot enter SMM in
> user-mode");
> -#else
>  do_smm_enter(cpu);
> -#endif /* CONFIG_USER_ONLY */
>  break;
>  case CPU_INTERRUPT_NMI:
>  cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0);
> @@ -1162,7 +1157,6 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>"Servicing hardware INT=0x%02x\n", intno);
>  do_interrupt_x86_hardirq(env, intno, 1);
>  break;
> -#if !defined(CONFIG_USER_ONLY)
>  case CPU_INTERRUPT_VIRQ:
>  /* FIXME: this should respect TPR */
>  cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
> @@ -1173,12 +1167,12 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  do_interrupt_x86_hardirq(env, intno, 1);
>  cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
>  break;
> -#endif
>  }
>
>  /* Ensure that no TB jump will be modified as the program flow was
> changed.  */
>  return true;
>  }
> +#endif /* CONFIG_USER_ONLY */
>
>  void helper_lldt(CPUX86State *env, int selector)
>  {
> diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
> index dce800a8953..fd86daf93d2 100644
> --- a/target/i386/tcg/tcg-cpu.c
> +++ b/target/i386/tcg/tcg-cpu.c
> @@ -72,12 +72,12 @@ static const struct TCGCPUOps x86_tcg_ops = {
>  .synchronize_from_tb = x86_cpu_synchronize_from_tb,
>  .cpu_exec_enter = x86_cpu_exec_enter,
>  .cpu_exec_exit = x86_cpu_exec_exit,
> -.cpu_exec_interrupt = x86_cpu_exec_interrupt,
>  .tlb_fill = x86_cpu_tlb_fill,
>  #ifdef CONFIG_USER_ONLY
>  .fake_user_exception = x86_cpu_do_interrupt,
>  #else
>  .do_interrupt = x86_cpu_do_interrupt,
> +.cpu_exec_interrupt = x86_cpu_exec_interrupt,
>  .debug_excp_handler = breakpoint_handler,
>  .debug_check_breakpoint = x86_debug_check_breakpoint,
>  #endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 12/24] target/m68k: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/m68k/cpu.h   |  2 ++
>  target/m68k/cpu.c   |  2 +-
>  target/m68k/op_helper.c | 16 +++-
>  3 files changed, 6 insertions(+), 14 deletions(-)
>

Reviewed-by: Warner Losh 



> diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
> index 997d588911c..550eb028b6e 100644
> --- a/target/m68k/cpu.h
> +++ b/target/m68k/cpu.h
> @@ -166,8 +166,10 @@ struct M68kCPU {
>  };
>
>
> +#ifndef CONFIG_USER_ONLY
>  void m68k_cpu_do_interrupt(CPUState *cpu);
>  bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>  void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
> diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
> index 72de6e97262..66d22d11895 100644
> --- a/target/m68k/cpu.c
> +++ b/target/m68k/cpu.c
> @@ -515,10 +515,10 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
>
>  static const struct TCGCPUOps m68k_tcg_ops = {
>  .initialize = m68k_tcg_init,
> -.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
>  .tlb_fill = m68k_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
>  .do_interrupt = m68k_cpu_do_interrupt,
>  .do_transaction_failed = m68k_cpu_transaction_failed,
>  #endif /* !CONFIG_USER_ONLY */
> diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
> index d006d1cb3ea..5d624838ae6 100644
> --- a/target/m68k/op_helper.c
> +++ b/target/m68k/op_helper.c
> @@ -24,18 +24,7 @@
>  #include "semihosting/semihost.h"
>  #include "tcg/tcg.h"
>
> -#if defined(CONFIG_USER_ONLY)
> -
> -void m68k_cpu_do_interrupt(CPUState *cs)
> -{
> -cs->exception_index = -1;
> -}
> -
> -static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
> -{
> -}
> -
> -#else
> +#if !defined(CONFIG_USER_ONLY)
>
>  static void cf_rte(CPUM68KState *env)
>  {
> @@ -516,7 +505,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr
> physaddr, vaddr addr,
>  cpu_loop_exit(cs);
>  }
>  }
> -#endif
>
>  bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -538,6 +526,8 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr)
>  {
>  CPUState *cs = env_cpu(env);
> --
> 2.31.1
>
>


Re: [PATCH 10/24] target/hppa: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/hppa/cpu.h| 4 ++--
>  target/hppa/cpu.c| 2 +-
>  target/hppa/int_helper.c | 7 ++-
>  3 files changed, 5 insertions(+), 8 deletions(-)
>

Reviewed-by: Warner Losh 


> diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
> index 748270bfa31..7854675b903 100644
> --- a/target/hppa/cpu.h
> +++ b/target/hppa/cpu.h
> @@ -325,13 +325,13 @@ int cpu_hppa_signal_handler(int host_signum, void
> *pinfo, void *puc);
>  hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
>  int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
>  int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> -void hppa_cpu_do_interrupt(CPUState *cpu);
> -bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
>  bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> MMUAccessType access_type, int mmu_idx,
> bool probe, uintptr_t retaddr);
>  #ifndef CONFIG_USER_ONLY
> +void hppa_cpu_do_interrupt(CPUState *cpu);
> +bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
>int type, hwaddr *pphys, int *pprot);
>  extern const MemoryRegionOps hppa_io_eir_ops;
> diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
> index 2eace4ee124..e8edd189bfc 100644
> --- a/target/hppa/cpu.c
> +++ b/target/hppa/cpu.c
> @@ -144,10 +144,10 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
>  static const struct TCGCPUOps hppa_tcg_ops = {
>  .initialize = hppa_translate_init,
>  .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
>  .tlb_fill = hppa_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
>  .do_interrupt = hppa_cpu_do_interrupt,
>  .do_unaligned_access = hppa_cpu_do_unaligned_access,
>  #endif /* !CONFIG_USER_ONLY */
> diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
> index 349495d3610..13073ae2bda 100644
> --- a/target/hppa/int_helper.c
> +++ b/target/hppa/int_helper.c
> @@ -88,7 +88,6 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg
> val)
>  eval_interrupt(env_archcpu(env));
>  qemu_mutex_unlock_iothread();
>  }
> -#endif /* !CONFIG_USER_ONLY */
>
>  void hppa_cpu_do_interrupt(CPUState *cs)
>  {
> @@ -100,7 +99,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
>  uint64_t iasq_f = env->iasq_f;
>  uint64_t iasq_b = env->iasq_b;
>
> -#ifndef CONFIG_USER_ONLY
>  target_ureg old_psw;
>
>  /* As documented in pa2.0 -- interruption handling.  */
> @@ -187,7 +185,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
>  env->iaoq_b = env->iaoq_f + 4;
>  env->iasq_f = 0;
>  env->iasq_b = 0;
> -#endif
>
>  if (qemu_loglevel_mask(CPU_LOG_INT)) {
>  static const char * const names[] = {
> @@ -248,7 +245,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
>
>  bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> -#ifndef CONFIG_USER_ONLY
>  HPPACPU *cpu = HPPA_CPU(cs);
>  CPUHPPAState *env = >env;
>
> @@ -258,6 +254,7 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  hppa_cpu_do_interrupt(cs);
>  return true;
>  }
> -#endif
>  return false;
>  }
> +
> +#endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 08/24] target/avr: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/avr/cpu.h| 2 ++
>  target/avr/cpu.c| 2 +-
>  target/avr/helper.c | 2 ++
>  3 files changed, 5 insertions(+), 1 deletion(-)
>

Reviewed-by: Warner Losh 


> diff --git a/target/avr/cpu.h b/target/avr/cpu.h
> index 93e3faa0a98..6f8c0ffd770 100644
> --- a/target/avr/cpu.h
> +++ b/target/avr/cpu.h
> @@ -156,8 +156,10 @@ typedef struct AVRCPU {
>
>  extern const struct VMStateDescription vms_avr_cpu;
>
> +#ifndef CONFIG_USER_ONLY
>  void avr_cpu_do_interrupt(CPUState *cpu);
>  bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>  hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
>  int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target/avr/cpu.c b/target/avr/cpu.c
> index ea14175ca55..e9fa54c9777 100644
> --- a/target/avr/cpu.c
> +++ b/target/avr/cpu.c
> @@ -195,10 +195,10 @@ static const struct SysemuCPUOps avr_sysemu_ops = {
>  static const struct TCGCPUOps avr_tcg_ops = {
>  .initialize = avr_cpu_tcg_init,
>  .synchronize_from_tb = avr_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = avr_cpu_exec_interrupt,
>  .tlb_fill = avr_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = avr_cpu_exec_interrupt,
>  .do_interrupt = avr_cpu_do_interrupt,
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/avr/helper.c b/target/avr/helper.c
> index 981c29da453..84e366d94a3 100644
> --- a/target/avr/helper.c
> +++ b/target/avr/helper.c
> @@ -25,6 +25,7 @@
>  #include "exec/address-spaces.h"
>  #include "exec/helper-proto.h"
>
> +#ifndef CONFIG_USER_ONLY
>  bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  bool ret = false;
> @@ -91,6 +92,7 @@ void avr_cpu_do_interrupt(CPUState *cs)
>
>  cs->exception_index = -1;
>  }
> +#endif /* !CONFIG_USER_ONLY */
>
>  int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
>  int len, bool is_write)
> --
> 2.31.1
>
>


Re: [PATCH 09/24] target/cris: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:18 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/cris/cpu.h|  2 +-
>  target/cris/cpu.c|  4 ++--
>  target/cris/helper.c | 17 ++---
>  3 files changed, 5 insertions(+), 18 deletions(-)
>

Reviewed-by: Warner Losh 


> diff --git a/target/cris/cpu.h b/target/cris/cpu.h
> index d3b64929096..be021899ae8 100644
> --- a/target/cris/cpu.h
> +++ b/target/cris/cpu.h
> @@ -185,11 +185,11 @@ struct CRISCPU {
>
>  #ifndef CONFIG_USER_ONLY
>  extern const VMStateDescription vmstate_cris_cpu;
> -#endif
>
>  void cris_cpu_do_interrupt(CPUState *cpu);
>  void crisv10_cpu_do_interrupt(CPUState *cpu);
>  bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif
>
>  void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
>
> diff --git a/target/cris/cpu.c b/target/cris/cpu.c
> index 70932b1f8c7..c2e7483f5bd 100644
> --- a/target/cris/cpu.c
> +++ b/target/cris/cpu.c
> @@ -205,20 +205,20 @@ static const struct SysemuCPUOps cris_sysemu_ops = {
>
>  static const struct TCGCPUOps crisv10_tcg_ops = {
>  .initialize = cris_initialize_crisv10_tcg,
> -.cpu_exec_interrupt = cris_cpu_exec_interrupt,
>  .tlb_fill = cris_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = cris_cpu_exec_interrupt,
>  .do_interrupt = crisv10_cpu_do_interrupt,
>  #endif /* !CONFIG_USER_ONLY */
>  };
>
>  static const struct TCGCPUOps crisv32_tcg_ops = {
>  .initialize = cris_initialize_tcg,
> -.cpu_exec_interrupt = cris_cpu_exec_interrupt,
>  .tlb_fill = cris_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = cris_cpu_exec_interrupt,
>  .do_interrupt = cris_cpu_do_interrupt,
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/cris/helper.c b/target/cris/helper.c
> index 911867f3b48..36926faf323 100644
> --- a/target/cris/helper.c
> +++ b/target/cris/helper.c
> @@ -41,20 +41,6 @@
>
>  #if defined(CONFIG_USER_ONLY)
>
> -void cris_cpu_do_interrupt(CPUState *cs)
> -{
> -CRISCPU *cpu = CRIS_CPU(cs);
> -CPUCRISState *env = >env;
> -
> -cs->exception_index = -1;
> -env->pregs[PR_ERP] = env->pc;
> -}
> -
> -void crisv10_cpu_do_interrupt(CPUState *cs)
> -{
> -cris_cpu_do_interrupt(cs);
> -}
> -
>  bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> MMUAccessType access_type, int mmu_idx,
> bool probe, uintptr_t retaddr)
> @@ -287,7 +273,6 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs,
> vaddr addr)
>  D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
>  return phy;
>  }
> -#endif
>
>  bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
> @@ -319,3 +304,5 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>
>  return ret;
>  }
> +
> +#endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 07/24] target/arm: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/arm/cpu.h | 3 +--
>  target/arm/cpu.c | 7 +--
>  target/arm/cpu_tcg.c | 6 +++---
>  3 files changed, 9 insertions(+), 7 deletions(-)
>

Reviewed-by: Warner Losh 

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 6a987f65e41..cfd755cff99 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1040,11 +1040,10 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t
> clustersz);
>
>  #ifndef CONFIG_USER_ONLY
>  extern const VMStateDescription vmstate_arm_cpu;
> -#endif
>
>  void arm_cpu_do_interrupt(CPUState *cpu);
>  void arm_v7m_cpu_do_interrupt(CPUState *cpu);
> -bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>
>  hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
>   MemTxAttrs *attrs);
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index d631c4683c4..ba0741b20e4 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -440,6 +440,8 @@ static void arm_cpu_reset(DeviceState *dev)
>  arm_rebuild_hflags(env);
>  }
>
> +#ifndef CONFIG_USER_ONLY
> +
>  static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
>   unsigned int target_el,
>   unsigned int cur_el, bool secure,
> @@ -556,7 +558,7 @@ static inline bool arm_excp_unmasked(CPUState *cs,
> unsigned int excp_idx,
>  return unmasked || pstate_unmasked;
>  }
>
> -bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> +static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  CPUClass *cc = CPU_GET_CLASS(cs);
>  CPUARMState *env = cs->env_ptr;
> @@ -608,6 +610,7 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  cc->tcg_ops->do_interrupt(cs);
>  return true;
>  }
> +#endif /* !CONFIG_USER_ONLY */
>
>  void arm_cpu_update_virq(ARMCPU *cpu)
>  {
> @@ -2010,11 +2013,11 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
>  static const struct TCGCPUOps arm_tcg_ops = {
>  .initialize = arm_translate_init,
>  .synchronize_from_tb = arm_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = arm_cpu_exec_interrupt,
>  .tlb_fill = arm_cpu_tlb_fill,
>  .debug_excp_handler = arm_debug_excp_handler,
>
>  #if !defined(CONFIG_USER_ONLY)
> +.cpu_exec_interrupt = arm_cpu_exec_interrupt,
>  .do_interrupt = arm_cpu_do_interrupt,
>  .do_transaction_failed = arm_cpu_do_transaction_failed,
>  .do_unaligned_access = arm_cpu_do_unaligned_access,
> diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
> index 33cc75af57d..0d5adccf1a7 100644
> --- a/target/arm/cpu_tcg.c
> +++ b/target/arm/cpu_tcg.c
> @@ -22,7 +22,7 @@
>  /* CPU models. These are not needed for the AArch64 linux-user build. */
>  #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
>
> -#ifdef CONFIG_TCG
> +#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
>  static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  {
>  CPUClass *cc = CPU_GET_CLASS(cs);
> @@ -46,7 +46,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  }
>  return ret;
>  }
> -#endif /* CONFIG_TCG */
> +#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
>
>  static void arm926_initfn(Object *obj)
>  {
> @@ -898,11 +898,11 @@ static void pxa270c5_initfn(Object *obj)
>  static const struct TCGCPUOps arm_v7m_tcg_ops = {
>  .initialize = arm_translate_init,
>  .synchronize_from_tb = arm_cpu_synchronize_from_tb,
> -.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
>  .tlb_fill = arm_cpu_tlb_fill,
>  .debug_excp_handler = arm_debug_excp_handler,
>
>  #if !defined(CONFIG_USER_ONLY)
> +.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
>  .do_interrupt = arm_v7m_cpu_do_interrupt,
>  .do_transaction_failed = arm_cpu_do_transaction_failed,
>  .do_unaligned_access = arm_cpu_do_unaligned_access,
> --
> 2.31.1
>
>


Re: [PATCH 06/24] target/alpha: Restrict cpu_exec_interrupt() handler to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> Restrict cpu_exec_interrupt() and its callees to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/alpha/cpu.h| 2 +-
>  target/alpha/cpu.c| 2 +-
>  target/alpha/helper.c | 5 ++---
>  3 files changed, 4 insertions(+), 5 deletions(-)
>

Reviewed-by: Warner Losh 


> diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
> index 82df108967b..4e993bd15bd 100644
> --- a/target/alpha/cpu.h
> +++ b/target/alpha/cpu.h
> @@ -274,10 +274,10 @@ struct AlphaCPU {
>
>  #ifndef CONFIG_USER_ONLY
>  extern const VMStateDescription vmstate_alpha_cpu;
> -#endif
>
>  void alpha_cpu_do_interrupt(CPUState *cpu);
>  bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
> +#endif /* !CONFIG_USER_ONLY */
>  void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
>  hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
> diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
> index 4871ad0c0a6..93e16a2ffb4 100644
> --- a/target/alpha/cpu.c
> +++ b/target/alpha/cpu.c
> @@ -218,10 +218,10 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
>
>  static const struct TCGCPUOps alpha_tcg_ops = {
>  .initialize = alpha_translate_init,
> -.cpu_exec_interrupt = alpha_cpu_exec_interrupt,
>  .tlb_fill = alpha_cpu_tlb_fill,
>
>  #ifndef CONFIG_USER_ONLY
> +.cpu_exec_interrupt = alpha_cpu_exec_interrupt,
>  .do_interrupt = alpha_cpu_do_interrupt,
>  .do_transaction_failed = alpha_cpu_do_transaction_failed,
>  .do_unaligned_access = alpha_cpu_do_unaligned_access,
> diff --git a/target/alpha/helper.c b/target/alpha/helper.c
> index 4f56fe4d231..81550d9e2ff 100644
> --- a/target/alpha/helper.c
> +++ b/target/alpha/helper.c
> @@ -293,7 +293,6 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int
> size,
>   prot, mmu_idx, TARGET_PAGE_SIZE);
>  return true;
>  }
> -#endif /* USER_ONLY */
>
>  void alpha_cpu_do_interrupt(CPUState *cs)
>  {
> @@ -348,7 +347,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
>
>  cs->exception_index = -1;
>
> -#if !defined(CONFIG_USER_ONLY)
>  switch (i) {
>  case EXCP_RESET:
>  i = 0x;
> @@ -404,7 +402,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
>
>  /* Switch to PALmode.  */
>  env->flags |= ENV_FLAG_PAL_MODE;
> -#endif /* !USER_ONLY */
>  }
>
>  bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> @@ -451,6 +448,8 @@ bool alpha_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>  return false;
>  }
>
> +#endif /* !CONFIG_USER_ONLY */
> +
>  void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags)
>  {
>  static const char linux_reg_names[31][4] = {
> --
> 2.31.1
>
>


Re: [RFC PATCH 04/24] accel/tcg: Rename user-mode do_interrupt hack as fake_user_exception

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> do_interrupt() is sysemu specific. However due to some X86
> specific hack, it is also used in user-mode emulation, which
> is why it couldn't be restricted to CONFIG_SOFTMMU (see the
> comment around added in commit 78271684719: "cpu: tcg_ops:
> move to tcg-cpu-ops.h, keep a pointer in CPUClass").
> Keep the hack but rename the handler as fake_user_exception()
> and restrict do_interrupt() to sysemu.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> RFC: Any better name / idea here?
>

Maybe user_mode_exception()? but I'm not sure that's better...


> ---
>  include/hw/core/tcg-cpu-ops.h | 22 ++
>  accel/tcg/cpu-exec.c  |  4 ++--
>  target/i386/tcg/tcg-cpu.c |  6 --
>  3 files changed, 20 insertions(+), 12 deletions(-)
>


Reviewed-by: Warner Losh 



> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
> index eab27d0c030..600f0349659 100644
> --- a/include/hw/core/tcg-cpu-ops.h
> +++ b/include/hw/core/tcg-cpu-ops.h
> @@ -37,14 +37,6 @@ struct TCGCPUOps {
>  void (*cpu_exec_exit)(CPUState *cpu);
>  /** @cpu_exec_interrupt: Callback for processing interrupts in
> cpu_exec */
>  bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
> -/**
> - * @do_interrupt: Callback for interrupt handling.
> - *
> - * note that this is in general SOFTMMU only, but it actually isn't
> - * because of an x86 hack (accel/tcg/cpu-exec.c), so we cannot put it
> - * in the SOFTMMU section in general.
> - */
> -void (*do_interrupt)(CPUState *cpu);
>  /**
>   * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
>   *
> @@ -61,6 +53,20 @@ struct TCGCPUOps {
>  void (*debug_excp_handler)(CPUState *cpu);
>
>  #ifdef NEED_CPU_H
> +#if defined(CONFIG_USER_ONLY) && defined(TARGET_I386)
> +/**
> + * @fake_user_exception: Callback for 'fake exception' handling.
> + *
> + * Simulate 'fake exception' which will be handled outside the
> + * cpu execution loop (hack for x86 user mode).
> + */
> +void (*fake_user_exception)(CPUState *cpu);
> +#else
> +/**
> + * @do_interrupt: Callback for interrupt handling.
> + */
> +void (*do_interrupt)(CPUState *cpu);
> +#endif /* !CONFIG_USER_ONLY || !TARGET_I386 */
>  #ifdef CONFIG_SOFTMMU
>  /**
>   * @do_transaction_failed: Callback for handling failed memory
> transactions
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index e5c0ccd1a2a..3e387c944c5 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -651,8 +651,8 @@ static inline bool cpu_handle_exception(CPUState *cpu,
> int *ret)
> loop */
>  #if defined(TARGET_I386)
>  CPUClass *cc = CPU_GET_CLASS(cpu);
> -cc->tcg_ops->do_interrupt(cpu);
> -#endif
> +cc->tcg_ops->fake_user_exception(cpu);
> +#endif /* TARGET_I386 */
>  *ret = cpu->exception_index;
>  cpu->exception_index = -1;
>  return true;
> diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
> index 93a79a57415..dce800a8953 100644
> --- a/target/i386/tcg/tcg-cpu.c
> +++ b/target/i386/tcg/tcg-cpu.c
> @@ -73,9 +73,11 @@ static const struct TCGCPUOps x86_tcg_ops = {
>  .cpu_exec_enter = x86_cpu_exec_enter,
>  .cpu_exec_exit = x86_cpu_exec_exit,
>  .cpu_exec_interrupt = x86_cpu_exec_interrupt,
> -.do_interrupt = x86_cpu_do_interrupt,
>  .tlb_fill = x86_cpu_tlb_fill,
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +.fake_user_exception = x86_cpu_do_interrupt,
> +#else
> +.do_interrupt = x86_cpu_do_interrupt,
>  .debug_excp_handler = breakpoint_handler,
>  .debug_check_breakpoint = x86_debug_check_breakpoint,
>  #endif /* !CONFIG_USER_ONLY */
> --
> 2.31.1
>
>


Re: [PATCH 03/24] target/i386: Simplify TARGET_X86_64 #ifdef'ry

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> Merge two TARGET_X86_64 consecutive blocks.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/i386/tcg/seg_helper.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>

Reviewed-by: Warner Losh 



>
> diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
> index 3ed20ca31d7..dee7bef68c6 100644
> --- a/target/i386/tcg/seg_helper.c
> +++ b/target/i386/tcg/seg_helper.c
> @@ -929,9 +929,7 @@ static void do_interrupt64(CPUX86State *env, int
> intno, int is_int,
> e2);
>  env->eip = offset;
>  }
> -#endif
>
> -#ifdef TARGET_X86_64
>  void helper_sysret(CPUX86State *env, int dflag)
>  {
>  int cpl, selector;
> @@ -984,7 +982,7 @@ void helper_sysret(CPUX86State *env, int dflag)
> DESC_W_MASK | DESC_A_MASK);
>  }
>  }
> -#endif
> +#endif /* TARGET_X86_64 */
>
>  /* real mode interrupt */
>  static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
> --
> 2.31.1
>
>


Re: [PATCH 02/24] target/i386: Restrict sysemu-only fpu_helper helpers

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> Restrict some sysemu-only fpu_helper helpers (see commit
> 83a3d9c7402: "i386: separate fpu_helper sysemu-only parts").
>
> Signed-off-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Warner Losh 


> ---
>  target/i386/cpu.h | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 6c50d3ab4f1..c241bc183d2 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1833,11 +1833,14 @@ void x86_cpu_list(void);
>  int cpu_x86_support_mca_broadcast(CPUX86State *env);
>
>  int cpu_get_pic_interrupt(CPUX86State *s);
> +
> +#ifndef CONFIG_USER_ONLY
>  /* MSDOS compatibility mode FPU exception support */
>  void x86_register_ferr_irq(qemu_irq irq);
>  void fpu_check_raise_ferr_irq(CPUX86State *s);
>  void cpu_set_ignne(void);
>  void cpu_clear_ignne(void);
> +#endif
>
>  /* mpx_helper.c */
>  void cpu_sync_bndcs_hflags(CPUX86State *env);
> --
> 2.31.1
>
>


Re: [PATCH 01/24] target/xtensa: Restrict do_transaction_failed() to sysemu

2021-09-02 Thread Warner Losh
On Thu, Sep 2, 2021 at 9:17 AM Philippe Mathieu-Daudé 
wrote:

> The do_transaction_failed() is restricted to system emulation since
> commit cbc183d2d9f ("cpu: move cc->transaction_failed to tcg_ops").
>
> Signed-off-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Warner Losh 


> ---
>  target/xtensa/cpu.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
> index 2345cb59c79..1e0cb1535ca 100644
> --- a/target/xtensa/cpu.h
> +++ b/target/xtensa/cpu.h
> @@ -568,10 +568,12 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr
> address, int size,
>   bool probe, uintptr_t retaddr);
>  void xtensa_cpu_do_interrupt(CPUState *cpu);
>  bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
> +#ifndef CONFIG_USER_ONLY
>  void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
> vaddr addr,
>unsigned size, MMUAccessType
> access_type,
>int mmu_idx, MemTxAttrs attrs,
>MemTxResult response, uintptr_t
> retaddr);
> +#endif /* !CONFIG_USER_ONLY */
>  void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
>  hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>  void xtensa_count_regs(const XtensaConfig *config,
> --
> 2.31.1
>
>


Re: [PATCH v2 4/9] escc: introduce escc_hard_reset_chn() for hardware reset

2021-09-02 Thread Mark Cave-Ayland

On 02/09/2021 20:31, Peter Maydell wrote:


On Thu, 2 Sept 2021 at 18:46, Mark Cave-Ayland
 wrote:


On 02/09/2021 16:42, Peter Maydell wrote:


On Thu, 2 Sept 2021 at 11:33, Mark Cave-Ayland
 wrote:


This new hardware reset function is to be called for both channels when the
hardware reset bit is written to register WR9. Its initial implementation is
the same as the existing escc_reset_chn() function used for device reset.

Signed-off-by: Mark Cave-Ayland 



The datasheet says the only differences between hard and soft
reset are for registers W9, W10, W11 and W14. I wasn't expecting
the functions to be completely separated out like this.


I did consider doing it that way, but felt having the 2 separate functions was 
the
easiest to read against the tables in the datasheet. What do you think would be 
the
best way to organise the reset functions?


I think having the hard-reset be "call the soft-reset and then
clear/set the handful of bits that hard-reset touches and
soft-reset doesn't" is probably clearer overall.


Okay thanks, I'll give that a go (probably tomorrow now...)


ATB,

Mark.



Re: [PATCH v2 4/9] escc: introduce escc_hard_reset_chn() for hardware reset

2021-09-02 Thread Peter Maydell
On Thu, 2 Sept 2021 at 18:46, Mark Cave-Ayland
 wrote:
>
> On 02/09/2021 16:42, Peter Maydell wrote:
>
> > On Thu, 2 Sept 2021 at 11:33, Mark Cave-Ayland
> >  wrote:
> >>
> >> This new hardware reset function is to be called for both channels when the
> >> hardware reset bit is written to register WR9. Its initial implementation 
> >> is
> >> the same as the existing escc_reset_chn() function used for device reset.
> >>
> >> Signed-off-by: Mark Cave-Ayland 
> >
> >
> > The datasheet says the only differences between hard and soft
> > reset are for registers W9, W10, W11 and W14. I wasn't expecting
> > the functions to be completely separated out like this.
>
> I did consider doing it that way, but felt having the 2 separate functions 
> was the
> easiest to read against the tables in the datasheet. What do you think would 
> be the
> best way to organise the reset functions?

I think having the hard-reset be "call the soft-reset and then
clear/set the handful of bits that hard-reset touches and
soft-reset doesn't" is probably clearer overall.

-- PMM



Re: [PATCH] hw/ssi: imx_spi: Improve chip select handling

2021-09-02 Thread Peter Maydell
On Thu, 2 Sept 2021 at 17:09, Guenter Roeck  wrote:
>
> On 9/2/21 8:58 AM, Peter Maydell wrote:
> > On Sun, 8 Aug 2021 at 02:34, Guenter Roeck  wrote:
> >>
> >> The control register does not really have a means to deselect
> >> all chip selects directly. As result, CS is effectively never
> >> deselected, and connected flash chips fail to perform read
> >> operations since they don't get the expected chip select signals
> >> to reset their state machine.
> >>
> >> Normally and per controller documentation one would assume that
> >> chip select should be set whenever a transfer starts (XCH is
> >> set or the tx fifo is written into), and that it should be disabled
> >> whenever a transfer is complete. However, that does not work in
> >> practice: attempts to implement this approach resulted in failures,
> >> presumably because a single transaction can be split into multiple
> >> transfers.
> >>
> >> At the same time, there is no explicit signal from the host indicating
> >> if chip select should be active or not. In the absence of such a direct
> >> signal, use the burst length written into the control register to
> >> determine if an access is ongoing or not. Disable all chip selects
> >> if the burst length field in the configuration register is set to 0,
> >> and (re-)enable chip select if a transfer is started. This is possible
> >> because the Linux driver clears the burst length field whenever it
> >> prepares the controller for the next transfer.
> >> This solution  is less than perfect since it effectively only disables
> >> chip select when initiating the next transfer, but it does work with
> >> Linux and should otherwise do no harm.
> >>
> >> Stop complaining if the burst length field is set to a value of 0,
> >> since that is done by Linux for every transfer.
> >>
> >> With this patch, a command line parameter such as "-drive
> >> file=flash.sabre,format=raw,if=mtd" can be used to instantiate the
> >> flash chip in the sabrelite emulation. Without this patch, the
> >> flash instantiates, but it only reads zeroes.
> >>
> >> Signed-off-by: Guenter Roeck 
> >> ---
> >> I am not entirely happy with this solution, but it is the best I was
> >> able to come up with. If anyone has a better idea, I'll be happy
> >> to give it a try.
> >>
> >>   hw/ssi/imx_spi.c | 17 +++--
> >>   1 file changed, 7 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
> >> index 189423bb3a..7a093156bd 100644
> >> --- a/hw/ssi/imx_spi.c
> >> +++ b/hw/ssi/imx_spi.c
> >> @@ -167,6 +167,8 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
> >>   DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
> >>   fifo32_num_used(>tx_fifo), fifo32_num_used(>rx_fifo));
> >>
> >> +qemu_set_irq(s->cs_lines[imx_spi_selected_channel(s)], 0);
> >> +
> >>   while (!fifo32_is_empty(>tx_fifo)) {
> >>   int tx_burst = 0;
> >>
> >> @@ -385,13 +387,6 @@ static void imx_spi_write(void *opaque, hwaddr 
> >> offset, uint64_t value,
> >>   case ECSPI_CONREG:
> >>   s->regs[ECSPI_CONREG] = value;
> >>
> >> -burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) 
> >> + 1;
> >> -if (burst % 8) {
> >> -qemu_log_mask(LOG_UNIMP,
> >> -  "[%s]%s: burst length %d not supported: 
> >> rounding up to next multiple of 8\n",
> >> -  TYPE_IMX_SPI, __func__, burst);
> >> -}
> >
> > Why has this log message been removed ?
>
> What I wanted to do is:
>
> "Stop complaining if the burst length field is set to a value of 0,
>   since that is done by Linux for every transfer."
>
> What I did instead is to remove the message entirely.
>
> How about the rest of the patch ? Is it worth a resend with the message
> restored (except for burst size == 0), or is it not acceptable anyway ?

I did the easy bit of the code review because answering this
question is probably a multiple-hour job...this is still on my
todo list, but I'm hoping somebody who understands the MIX
SPI device gets to it first.

-- PMM



[PATCH] hw/arm: Add support for kudo-bmc board.

2021-09-02 Thread Chris Rauer
kudo-bmc is a board supported by OpenBMC.
https://github.com/openbmc/openbmc/tree/master/meta-fii/meta-kudo

Tested: Booted kudo firmware.
Signed-off-by: Chris Rauer 
---
 docs/system/arm/nuvoton.rst |  1 +
 hw/arm/npcm7xx_boards.c | 34 ++
 2 files changed, 35 insertions(+)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 69f57c2886..adf497e679 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -20,6 +20,7 @@ Hyperscale applications. The following machines are based on 
this chip :
 
 - ``quanta-gbs-bmc``Quanta GBS server BMC
 - ``quanta-gsj``Quanta GSJ server BMC
+- ``kudo-bmc``  Fii USA Kudo server BMC
 
 There are also two more SoCs, NPCM710 and NPCM705, which are single-core
 variants of NPCM750 and NPCM730, respectively. These are currently not
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index e5a3243995..c80f442adb 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -31,6 +31,7 @@
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
 #define QUANTA_GBS_POWER_ON_STRAPS 0x17ff
+#define KUDO_BMC_POWER_ON_STRAPS 0x1fff
 
 static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
 
@@ -357,6 +358,23 @@ static void quanta_gbs_init(MachineState *machine)
 npcm7xx_load_kernel(machine, soc);
 }
 
+static void kudo_bmc_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, KUDO_BMC_POWER_ON_STRAPS);
+npcm7xx_connect_dram(soc, machine->ram);
+qdev_realize(DEVICE(soc), NULL, _fatal);
+
+npcm7xx_load_bootrom(machine, soc);
+npcm7xx_connect_flash(>fiu[0], 0, "mx66u51235f",
+  drive_get(IF_MTD, 0, 0));
+npcm7xx_connect_flash(>fiu[1], 0, "mx66u51235f",
+  drive_get(IF_MTD, 3, 0));
+
+npcm7xx_load_kernel(machine, soc);
+}
+
 static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
 {
 NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
@@ -417,6 +435,18 @@ static void gbs_bmc_machine_class_init(ObjectClass *oc, 
void *data)
 mc->default_ram_size = 1 * GiB;
 }
 
+static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
+MachineClass *mc = MACHINE_CLASS(oc);
+
+npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
+
+mc->desc = "Kudo BMC (Cortex A9)";
+mc->init = kudo_bmc_init;
+mc->default_ram_size = 1 * GiB;
+};
+
 static const TypeInfo npcm7xx_machine_types[] = {
 {
 .name   = TYPE_NPCM7XX_MACHINE,
@@ -437,6 +467,10 @@ static const TypeInfo npcm7xx_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
 .parent = TYPE_NPCM7XX_MACHINE,
 .class_init = gbs_bmc_machine_class_init,
+}, {
+.name   = MACHINE_TYPE_NAME("kudo-bmc"),
+.parent = TYPE_NPCM7XX_MACHINE,
+.class_init = kudo_bmc_machine_class_init,
 },
 };
 
-- 
2.33.0.153.gba50c8fa24-goog




Re: [PATCH v2 4/9] escc: introduce escc_hard_reset_chn() for hardware reset

2021-09-02 Thread Mark Cave-Ayland

On 02/09/2021 16:42, Peter Maydell wrote:


On Thu, 2 Sept 2021 at 11:33, Mark Cave-Ayland
 wrote:


This new hardware reset function is to be called for both channels when the
hardware reset bit is written to register WR9. Its initial implementation is
the same as the existing escc_reset_chn() function used for device reset.

Signed-off-by: Mark Cave-Ayland 



The datasheet says the only differences between hard and soft
reset are for registers W9, W10, W11 and W14. I wasn't expecting
the functions to be completely separated out like this.


I did consider doing it that way, but felt having the 2 separate functions was the 
easiest to read against the tables in the datasheet. What do you think would be the 
best way to organise the reset functions?



ATB,

Mark.



[PATCH v2 3/5] hw/virtio: Remove NULL check in virtio_free_region_cache()

2021-09-02 Thread Philippe Mathieu-Daudé
virtio_free_region_cache() is called within call_rcu(),
always with a non-NULL argument. Ensure new code keep it
that way by replacing the NULL check by an assertion.
Add a comment this function is called within call_rcu().

Reviewed-by: Stefano Garzarella 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Philippe Mathieu-Daudé 
---
Worth mentioning the left-over from c611c76417f?
("virtio: add MemoryListener to cache ring translations")
---
 hw/virtio/virtio.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index b37344bb5e1..97f60017466 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -133,12 +133,10 @@ struct VirtQueue
 QLIST_ENTRY(VirtQueue) node;
 };
 
+/* Called within call_rcu().  */
 static void virtio_free_region_cache(VRingMemoryRegionCaches *caches)
 {
-if (!caches) {
-return;
-}
-
+assert(caches != NULL);
 address_space_cache_destroy(>desc);
 address_space_cache_destroy(>avail);
 address_space_cache_destroy(>used);
-- 
2.31.1




[PATCH v2 5/5] hw/virtio: Have virtqueue_get_avail_bytes() pass caches arg to callees

2021-09-02 Thread Philippe Mathieu-Daudé
Both virtqueue_packed_get_avail_bytes() and
virtqueue_split_get_avail_bytes() access the region cache, but
their caller also does. Simplify by having virtqueue_get_avail_bytes
calling both with RCU lock held, and passing the caches as argument.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/virtio/virtio.c | 29 -
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7d3bf9091ee..0dbfb53e51b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -985,28 +985,23 @@ static int virtqueue_split_read_next_desc(VirtIODevice 
*vdev, VRingDesc *desc,
 return VIRTQUEUE_READ_DESC_MORE;
 }
 
+/* Called within rcu_read_lock().  */
 static void virtqueue_split_get_avail_bytes(VirtQueue *vq,
 unsigned int *in_bytes, unsigned int *out_bytes,
-unsigned max_in_bytes, unsigned max_out_bytes)
+unsigned max_in_bytes, unsigned max_out_bytes,
+VRingMemoryRegionCaches *caches)
 {
 VirtIODevice *vdev = vq->vdev;
 unsigned int max, idx;
 unsigned int total_bufs, in_total, out_total;
-VRingMemoryRegionCaches *caches;
 MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
 int64_t len = 0;
 int rc;
 
-RCU_READ_LOCK_GUARD();
-
 idx = vq->last_avail_idx;
 total_bufs = in_total = out_total = 0;
 
 max = vq->vring.num;
-caches = vring_get_region_caches(vq);
-if (!caches) {
-goto err;
-}
 
 while ((rc = virtqueue_num_heads(vq, idx)) > 0) {
 MemoryRegionCache *desc_cache = >desc;
@@ -1125,32 +1120,28 @@ static int virtqueue_packed_read_next_desc(VirtQueue 
*vq,
 return VIRTQUEUE_READ_DESC_MORE;
 }
 
+/* Called within rcu_read_lock().  */
 static void virtqueue_packed_get_avail_bytes(VirtQueue *vq,
  unsigned int *in_bytes,
  unsigned int *out_bytes,
  unsigned max_in_bytes,
- unsigned max_out_bytes)
+ unsigned max_out_bytes,
+ VRingMemoryRegionCaches *caches)
 {
 VirtIODevice *vdev = vq->vdev;
 unsigned int max, idx;
 unsigned int total_bufs, in_total, out_total;
 MemoryRegionCache *desc_cache;
-VRingMemoryRegionCaches *caches;
 MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
 int64_t len = 0;
 VRingPackedDesc desc;
 bool wrap_counter;
 
-RCU_READ_LOCK_GUARD();
 idx = vq->last_avail_idx;
 wrap_counter = vq->last_avail_wrap_counter;
 total_bufs = in_total = out_total = 0;
 
 max = vq->vring.num;
-caches = vring_get_region_caches(vq);
-if (!caches) {
-goto err;
-}
 
 for (;;) {
 unsigned int num_bufs = total_bufs;
@@ -1251,6 +1242,8 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
int *in_bytes,
 uint16_t desc_size;
 VRingMemoryRegionCaches *caches;
 
+RCU_READ_LOCK_GUARD();
+
 if (unlikely(!vq->vring.desc)) {
 goto err;
 }
@@ -1269,10 +1262,12 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
int *in_bytes,
 
 if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
 virtqueue_packed_get_avail_bytes(vq, in_bytes, out_bytes,
- max_in_bytes, max_out_bytes);
+ max_in_bytes, max_out_bytes,
+ caches);
 } else {
 virtqueue_split_get_avail_bytes(vq, in_bytes, out_bytes,
-max_in_bytes, max_out_bytes);
+max_in_bytes, max_out_bytes,
+caches);
 }
 
 return;
-- 
2.31.1




[PATCH v2 2/5] hw/virtio: Comment virtqueue_flush() must be called with RCU read lock

2021-09-02 Thread Philippe Mathieu-Daudé
Reported-by: Stefano Garzarella 
Suggested-by: Stefan Hajnoczi 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/virtio/virtio.h | 7 +++
 hw/virtio/virtio.c | 1 +
 2 files changed, 8 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 8bab9cfb750..c1c5f6e53c8 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -186,6 +186,13 @@ void virtio_delete_queue(VirtQueue *vq);
 
 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
 unsigned int len);
+/**
+ * virtqueue_flush:
+ * @vq: The #VirtQueue
+ * @count: Number of elements to flush
+ *
+ * Must be called within RCU critical section.
+ */
 void virtqueue_flush(VirtQueue *vq, unsigned int count);
 void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem,
   unsigned int len);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a5214bca612..b37344bb5e1 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -898,6 +898,7 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned 
int count)
 }
 }
 
+/* Called within rcu_read_lock().  */
 void virtqueue_flush(VirtQueue *vq, unsigned int count)
 {
 if (virtio_device_disabled(vq->vdev)) {
-- 
2.31.1




[PATCH v2 4/5] hw/virtio: Acquire RCU read lock in virtqueue_packed_drop_all()

2021-09-02 Thread Philippe Mathieu-Daudé
vring_get_region_caches() must be called with the RCU read lock
acquired. virtqueue_packed_drop_all() does not, and uses the
'caches' pointer. Fix that by using the RCU_READ_LOCK_GUARD()
macro.

Reported-by: Stefano Garzarella 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/virtio/virtio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 97f60017466..7d3bf9091ee 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1704,6 +1704,8 @@ static unsigned int virtqueue_packed_drop_all(VirtQueue 
*vq)
 VirtIODevice *vdev = vq->vdev;
 VRingPackedDesc desc;
 
+RCU_READ_LOCK_GUARD();
+
 caches = vring_get_region_caches(vq);
 if (!caches) {
 return 0;
-- 
2.31.1




[PATCH v2 1/5] hw/virtio: Document virtio_queue_packed_empty_rcu is called within RCU

2021-09-02 Thread Philippe Mathieu-Daudé
While virtio_queue_packed_empty_rcu() uses the '_rcu' suffix,
it is not obvious it is called within rcu_read_lock(). All other
functions from this file called with the RCU locked have a comment
describing it. Document this one similarly for consistency.

Reviewed-by: Stefano Garzarella 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/virtio/virtio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 874377f37a7..a5214bca612 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -634,6 +634,7 @@ static int virtio_queue_split_empty(VirtQueue *vq)
 return empty;
 }
 
+/* Called within rcu_read_lock().  */
 static int virtio_queue_packed_empty_rcu(VirtQueue *vq)
 {
 struct VRingPackedDesc desc;
-- 
2.31.1




[PATCH v2 0/5] hw/virtio: Minor housekeeping patches

2021-09-02 Thread Philippe Mathieu-Daudé
Hi,

This series contains few patches I gathered while tooking notes
trying to understand issues #300-#302.

Since v1:
- Added virtqueue_flush comment (Stefano)
- Call RCU_READ_LOCK_GUARD in virtqueue_packed_drop_all (Stefano)

Philippe Mathieu-Daudé (5):
  hw/virtio: Document virtio_queue_packed_empty_rcu is called within RCU
  hw/virtio: Comment virtqueue_flush() must be called with RCU read lock
  hw/virtio: Remove NULL check in virtio_free_region_cache()
  hw/virtio: Acquire RCU read lock in virtqueue_packed_drop_all()
  hw/virtio: Have virtqueue_get_avail_bytes() pass caches arg to callees

 include/hw/virtio/virtio.h |  7 +++
 hw/virtio/virtio.c | 39 ++
 2 files changed, 25 insertions(+), 21 deletions(-)

-- 
2.31.1





  1   2   3   4   5   >