[CORE] vmm_scheduler: Don't enqueue woken-up VCPU in vmm_scheduler_next()

The vmm_scheduler_state_change() function enqueues a woken-up VCPU
(i.e. VCPU put-in READY state) to ready queue hence no need to enqueue
it again in vmm_scheduler_next() function.

This patch does above described minor fix in vmm_scheduler_next()

Signed-off-by: Anup Patel <anup@brainfault.org>
[ARM] arm32ve: Check VCPU feature when emulating AUXCTRL register write

Signed-off-by: Anup Patel <anup@brainfault.org>
[ARM] arm32ve: print more info when we get an unexpected exception

This patch increases the information printed upon getting an
unexpected exception so that we can debug better.

Signed-off-by: Anup Patel <anup@brainfault.org>
[LIBS] fifo: Use spinlock lite APIs to improve performance

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] Simplify SMP IPIs using FIFO APIs

This patch reduces duplicate code in implementing per host CPU
IPI list by using FIFO APIs to implement per host CPU IPI FIFO.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] vmm_vcpu_irq: improve locking for vcpu irqs

We have per-VCPU spin lock for VCPU irqs to protect the members of
virtual irq related info.

This patch fixes usage of the VCPU irqs spin lock by making sure
that lock is not held when VCPU irq functions call someother function
elsewhere. This will avoid potential deadlocks because the external
function that is being called might use spin lock or other locks or
may even preempt.

Signed-off-by: Anup Patel <anup@brainfault.org>
[ARM] vgic: Improve locking for distributor state

The VGIC VCPU context of a VCPU will only be accessed when the VCPU
is current VCPU hence avoid locking for __vgic_save_vcpu_hwstate()
and __vgic_restore_vcpu_hwstate().

On the other hand, the VGIC distributor context needs to be protected
since a SMP Guest will have multiple VCPUs (running on different host
CPUs) accessing common distributor context hence we rename our VGIC
state lock to VGIC distributor lock.

Further, VGIC distributor lock should not be held when calling someother
function elsewhere. This will avoid potential deadlocks because the external
function that is being called might use spinlock or even indirectly call
VGIC code via IPIs.

This patch does the above described improvements to the VGIC emulator.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] More passive and lazy load balancer

This patch makes our existing crude load balancer more passive
and lazy running in background as Orphan VCPU on host CPU0.

Now the manager also provide APIs to change host CPU assigned
to a VCPU and uses this APIs in updated load balancer.

With this patch, we have UP Guest and SMP Guest booting on
SMP host (i.e. VExpress-A15) emulated by ARM fast models.

Also, having such a lazy load balancer running in background
will keep the load balancing overhead to minimum.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] Increase max IPIs per host CPU

Limiting max IPIs to be host CPU count seems to be an underestimate
of required number of max IPIs per host CPU. Due to this we quite
frequently run out of space in IPI fifo.

For now, this patch set max IPIs per host CPU to max VCPU count.

Signed-off-by: Anup Patel <anup@brainfault.org>
[EMULATORS] pl011: Make locking SMP friendly

The pl011 state lock should not be held when calling vmm_devemu APIs. This
is to avoid potential deadlocks and race-conditions.

Signed-off-by: Anup Patel <anup@brainfault.org>
[EMULATORS] arm_mptimer: Make locking SMP friendly

The arm_mptimer state lock should not be held when calling vmm_devemu APIs.
This is to avoid potential deadlocks and race-conditions.

Signed-off-by: Anup Patel <anup@brainfault.org>
[ARM] arm32ve: Print HPFAR, HIFAR, and HDFAR for unexpected exceptions

The status of HPFAR, HIFAR, and HDFAR register could be useful for
debugging unexpected exceptions hence print these registers.

Signed-off-by: Anup Patel <anup@brainfault.org>
[EMULATORS] gic: Avoid calling vmm_devemu APIs with spinlock held

We should not call vmm_devemu APIs with gic state spinlock held. This
is to avoid potential spinlock related deadlocks on SMP host.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] vmm_vcpu_irq: Protect arch_vcpu_irq_xxx() using vcpu irqs spinlock

For SMP Guest running on SMP host, we don't want multiple host CPUs to
execute arch_vcpu_irq_xxx() simultaneously for given VCPU hence, we use
vcpu irqs spinlock to protect calls to arch_vcpu_irq_xxx().

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] Make vmm_manager_vcpu_set_hcpu() SMP safe

This patch makes vmm_manager_vcpu_set_hcpu() more atomic and SMP
safe so that when load balancer changes host CPU assigned to VCPU,
the VCPU transition from one host CPU to another occurs without
interruption and deadlocks.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] Minor improvements to crude load balancer

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] vmm_timer: Make timer event operations SMP safe

Till no we only have per-CPU active event list which as protected
by spinlock for SMP safe access but on SMP host the timer event
start/stop operations also need to be SMP safe.

This patch adds a spinlock to timer event for making event start
and stop operations SMP safe.

Signed-off-by: Anup Patel <anup@brainfault.org>
[ARM] generic_timer: Minor fixes and cleanups

We can get an spurious interrupt on buggy hardware or buggy simulator
hence ignore spurious interrupts

Further, on SMP host we can also get virtual/physical interrupt meant
for normal VCPU which was previous running hence ignore interrupt
in this case too.

This patch also does lot of code cleanups.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] More improvements to vmm_scheduler_next()

This patch reduces code duplicay in vmm_scheduler_next for
"Normal scheduling" case.

We also protect arch_vcpu_switch() using sched_lock of current
and next VCPUs.

Signed-off-by: Anup Patel <anup@brainfault.org>
[CORE] Avoid using vmm_manager_vcpu_iterate() in load balancing

The vmm_manager_vcpu_iterate() acquires manager lock and then
iterates over each VCPU. This API is good for stuff like statistic
gathering or listing or count specific types of VCPU but not good
for heavy task like moving VCPU from one host CPU to another.

In future, we would only use vmm_manager_vcpu_iterate() for very
lightweight task as described above.

Signed-off-by: Anup Patel <anup@brainfault.org>