[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 1/4] xen/arm: Implement PSCI SYSTEM_SUSPEND call for guests
Hi Jürgen, On Mon, Jul 21, 2025 at 11:08 AM Jürgen Groß <jgross@xxxxxxxx> wrote: > > On 28.06.25 20:17, Julien Grall wrote: > > Hi Mykola, > > > > On 27/06/2025 11:51, Mykola Kvach wrote: > >> diff --git a/xen/arch/arm/include/asm/perfc_defn.h > >> b/xen/arch/arm/include/asm/ > >> perfc_defn.h > >> index effd25b69e..8dfcac7e3b 100644 > >> --- a/xen/arch/arm/include/asm/perfc_defn.h > >> +++ b/xen/arch/arm/include/asm/perfc_defn.h > >> @@ -33,6 +33,7 @@ PERFCOUNTER(vpsci_system_reset, "vpsci: > >> system_reset") > >> PERFCOUNTER(vpsci_cpu_suspend, "vpsci: cpu_suspend") > >> PERFCOUNTER(vpsci_cpu_affinity_info, "vpsci: cpu_affinity_info") > >> PERFCOUNTER(vpsci_features, "vpsci: features") > >> +PERFCOUNTER(vpsci_system_suspend, "vpsci: system_suspend") > >> PERFCOUNTER(vcpu_kick, "vcpu: notify other vcpu") > >> diff --git a/xen/arch/arm/include/asm/psci.h > >> b/xen/arch/arm/include/asm/psci.h > >> index 4780972621..48a93e6b79 100644 > >> --- a/xen/arch/arm/include/asm/psci.h > >> +++ b/xen/arch/arm/include/asm/psci.h > >> @@ -47,10 +47,12 @@ void call_psci_system_reset(void); > >> #define PSCI_0_2_FN32_SYSTEM_OFF PSCI_0_2_FN32(8) > >> #define PSCI_0_2_FN32_SYSTEM_RESET PSCI_0_2_FN32(9) > >> #define PSCI_1_0_FN32_PSCI_FEATURES PSCI_0_2_FN32(10) > >> +#define PSCI_1_0_FN32_SYSTEM_SUSPEND PSCI_0_2_FN32(14) > >> #define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) > >> #define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) > >> #define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) > >> +#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) > >> /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ > >> #define PSCI_0_2_AFFINITY_LEVEL_ON 0 > >> diff --git a/xen/arch/arm/include/asm/vpsci.h > >> b/xen/arch/arm/include/asm/vpsci.h > >> index 0cca5e6830..69d40f9d7f 100644 > >> --- a/xen/arch/arm/include/asm/vpsci.h > >> +++ b/xen/arch/arm/include/asm/vpsci.h > >> @@ -23,7 +23,7 @@ > >> #include <asm/psci.h> > >> /* Number of function implemented by virtual PSCI (only 0.2 or later) */ > >> -#define VPSCI_NR_FUNCS 12 > >> +#define VPSCI_NR_FUNCS 14 > >> /* Functions handle PSCI calls from the guests */ > >> bool do_vpsci_0_1_call(struct cpu_user_regs *regs, uint32_t fid); > >> diff --git a/xen/arch/arm/mmu/p2m.c b/xen/arch/arm/mmu/p2m.c > >> index 67296dabb5..f9c09a49e2 100644 > >> --- a/xen/arch/arm/mmu/p2m.c > >> +++ b/xen/arch/arm/mmu/p2m.c > >> @@ -6,6 +6,8 @@ > >> #include <xen/sched.h> > >> #include <xen/softirq.h> > >> +#include <public/sched.h> > >> + > >> #include <asm/alternative.h> > >> #include <asm/event.h> > >> #include <asm/flushtlb.h> > >> @@ -198,7 +200,9 @@ void dump_p2m_lookup(struct domain *d, paddr_t addr) > >> */ > >> void p2m_save_state(struct vcpu *p) > >> { > >> - p->arch.sctlr = READ_SYSREG(SCTLR_EL1); > >> + if ( !(p->domain->is_shutting_down && > >> + p->domain->shutdown_code == SHUTDOWN_suspend) ) > > > > This is definitely not obvious why you need to change p2m_save_state(). > > AFAIU, > > you are doing this because when suspending the system, you will overwrite p- > > >arch.sctlr. However, this is super fragile. For instance, you still seem > > to > > overwrite TTBR{0,1} and TTBCR. > > > > TTBR{0,1} are technically unknown at boot. So it is fine to ignore them. > > But > > for TTBCR, I am not 100% whether this is supposed to be unknown. > > > > Anyway, adding more "if (...)" is not the right solution because in the > > future > > we may decide to reset more registers. > > > > It would be better if we stash the value sand then update the registers. > > Another > > possibility would be to entirely skip the save path for CPUs that are > > turned off > > (after all this is a bit useless work...). > > > >> +static int do_common_cpu_on(register_t target_cpu, register_t entry_point, > >> + register_t context_id) > >> +{ > >> + int rc; > >> + struct vcpu *v; > >> + struct domain *d = current->domain; > >> + register_t vcpuid; > >> + > >> + vcpuid = vaffinity_to_vcpuid(target_cpu); > >> + > >> + if ( (v = domain_vcpu(d, vcpuid)) == NULL ) > >> + return PSCI_INVALID_PARAMETERS; > >> + > >> + if ( !test_bit(_VPF_down, &v->pause_flags) ) > >> + return PSCI_ALREADY_ON; > >> + > >> + rc = do_setup_vcpu_ctx(v, entry_point, context_id); > >> + if ( rc == PSCI_SUCCESS ) > >> + vcpu_wake(v); > >> + > >> + return rc; > >> +} > >> + > >> static int32_t do_psci_cpu_on(uint32_t vcpuid, register_t entry_point) > >> { > >> int32_t ret; > >> @@ -197,6 +208,52 @@ static void do_psci_0_2_system_reset(void) > >> domain_shutdown(d,SHUTDOWN_reboot); > >> } > >> +static void do_resume_on_error(struct domain *d) > > > > This looks like an open-coding version of domain_resume() without the > > domain_{,un}pause(). What worries me is there is a comment on top of > > domain_pause() explaining why it is called. I understand, we can't call > > domain_pause() here (it doesn't work on the current domain). However, it > > feels > > to me there is an explanation necessary why this is fine to diverge. > > > > I am not a scheduler expert, so I am CCing Juergen in the hope he could > > provide > > some inputs. > > I don't think the reason for domain_[un]pause() is directly scheduling > related. > > It seems to be x86 specific for shadow page table handling. > > In any case I'd suggest to split domain_resume() into 2 functions, one > of them (e.g. domain_resume_nopause()) replacing do_resume_on_error() > and domain_resume() just pausing the domain, calling the new function, > and then unpausing the domain again. Got it — thank you for the review! > > Another option might be to move the suspend action into a tasklet, enabling > to call domain_resume() directly if needed. I didn't check whether other > constraints even allow this idea, though. > > > Juergen Best regards, Mykola
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |