All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Baicar, Tyler" <tbaicar@codeaurora.org>
To: Marc Zyngier <marc.zyngier@arm.com>,
	christoffer.dall@linaro.org, pbonzini@redhat.com,
	rkrcmar@redhat.com, linux@armlinux.org.uk,
	catalin.marinas@arm.com, will.deacon@arm.com, rjw@rjwysocki.net,
	lenb@kernel.org, matt@codeblueprint.co.uk,
	robert.moore@intel.com, lv.zheng@intel.com, nkaje@codeaurora.org,
	zjzhang@codeaurora.org, mark.rutland@arm.com,
	james.morse@arm.com, akpm@linux-foundation.org,
	eun.taik.lee@samsung.com, sandeepa.s.prabhu@gmail.com,
	labbott@redhat.com, shijie.huang@arm.com,
	rruigrok@codeaurora.org, paul.gortmaker@windriver.com,
	tn@semihalf.com, fu.wei@linaro.org, rostedt@goodmis.org,
	bristot@redhat.com, linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	linux-efi@vger.kernel.org, devel@acpica.org,
	Suzuki.Poulose@arm.com, punit.agrawal@arm.com, astone@redhat.com
Subject: Re: [PATCH V13 10/10] arm/arm64: KVM: add guest SEA support
Date: Tue, 28 Mar 2017 10:35:22 -0600	[thread overview]
Message-ID: <ba39628f-f389-afe2-ea45-4b1e2de5c2e9@codeaurora.org> (raw)
In-Reply-To: <bb4b4608-85ba-fd20-53b1-c19d99019de1@arm.com>

Hello Marc,


On 3/24/2017 8:03 AM, Marc Zyngier wrote:
> On 21/03/17 22:47, Tyler Baicar wrote:
>> Currently external aborts are unsupported by the guest abort
>> handling. Add handling for SEAs so that the host kernel reports
>> SEAs which occur in the guest kernel.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> ---
>>   arch/arm/include/asm/kvm_arm.h       | 10 +++++++++
>>   arch/arm/include/asm/system_misc.h   |  5 +++++
>>   arch/arm/kvm/mmu.c                   | 41 ++++++++++++++++++++++++++++++------
>>   arch/arm64/include/asm/kvm_arm.h     | 10 +++++++++
>>   arch/arm64/include/asm/system_misc.h |  2 ++
>>   arch/arm64/mm/fault.c                | 19 +++++++++++++++--
>>   drivers/acpi/apei/ghes.c             | 13 ++++++------
>>   include/acpi/ghes.h                  |  2 +-
>>   8 files changed, 86 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
>> index a3f0b3d..ebf020b 100644
>> --- a/arch/arm/include/asm/kvm_arm.h
>> +++ b/arch/arm/include/asm/kvm_arm.h
>> @@ -187,6 +187,16 @@
>>   #define FSC_FAULT	(0x04)
>>   #define FSC_ACCESS	(0x08)
>>   #define FSC_PERM	(0x0c)
>> +#define FSC_SEA		(0x10)
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~0xf)
>> diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
>> index a3d61ad..ea45d94 100644
>> --- a/arch/arm/include/asm/system_misc.h
>> +++ b/arch/arm/include/asm/system_misc.h
>> @@ -24,4 +24,9 @@
>>   
>>   #endif /* !__ASSEMBLY__ */
>>   
>> +static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	return -1;
>> +}
>> +
> Shouldn't this be in the #ifndef __ASSEMBLY__ block? The assembler is
> definitely going to barf on that...
I will move this in the next patch set.
>>   #endif /* __ASM_ARM_SYSTEM_MISC_H */
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index 962616f..105b6ab 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -29,6 +29,7 @@
>>   #include <asm/kvm_asm.h>
>>   #include <asm/kvm_emulate.h>
>>   #include <asm/virt.h>
>> +#include <asm/system_misc.h>
>>   
>>   #include "trace.h"
>>   
>> @@ -1406,6 +1407,24 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>>   		kvm_set_pfn_accessed(pfn);
>>   }
>>   
>> +static bool is_abort_synchronous(unsigned long fault_status) {
>> +	switch (fault_status) {
>> +	case FSC_SEA:
>> +	case FSC_SEA_TTW0:
>> +	case FSC_SEA_TTW1:
>> +	case FSC_SEA_TTW2:
>> +	case FSC_SEA_TTW3:
>> +	case FSC_SECC:
>> +	case FSC_SECC_TTW0:
>> +	case FSC_SECC_TTW1:
>> +	case FSC_SECC_TTW2:
>> +	case FSC_SECC_TTW3:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>>   /**
>>    * kvm_handle_guest_abort - handles all 2nd stage aborts
>>    * @vcpu:	the VCPU pointer
>> @@ -1426,23 +1445,31 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>   	unsigned long hva;
>>   	bool is_iabt, write_fault, writable;
>>   	gfn_t gfn;
>> -	int ret, idx;
>> +	int ret, idx, sea_status = 1;
>> +
>> +	/* Check the stage-2 fault is trans. fault or write fault */
>> +	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>> +
>> +	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> +
>> +	/* The host kernel will handle the synchronous external abort. There
>> +	 * is no need to pass the error into the guest.
>> +	 */
>> +	if (is_abort_synchronous(fault_status))
>> +		sea_status = handle_guest_sea((unsigned long)fault_ipa,
>> +				    kvm_vcpu_get_hsr(vcpu));
>>   
>>   	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>> -	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) {
>> +	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu)) && sea_status) {
>>   		kvm_inject_vabt(vcpu);
>>   		return 1;
>>   	}
>>   
>> -	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> -
>>   	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
>>   			      kvm_vcpu_get_hfar(vcpu), fault_ipa);
>>   
>> -	/* Check the stage-2 fault is trans. fault or write fault */
>> -	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>>   	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
>> -	    fault_status != FSC_ACCESS) {
>> +	    fault_status != FSC_ACCESS && sea_status) {
>>   		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
>>   			kvm_vcpu_trap_get_class(vcpu),
>>   			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
>> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
>> index 6e99978..61d694c 100644
>> --- a/arch/arm64/include/asm/kvm_arm.h
>> +++ b/arch/arm64/include/asm/kvm_arm.h
>> @@ -204,6 +204,16 @@
>>   #define FSC_FAULT	ESR_ELx_FSC_FAULT
>>   #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
>>   #define FSC_PERM	ESR_ELx_FSC_PERM
>> +#define FSC_SEA		ESR_ELx_FSC_EXTABT
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~UL(0xf))
>> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
>> index bc81243..5b2cecd 100644
>> --- a/arch/arm64/include/asm/system_misc.h
>> +++ b/arch/arm64/include/asm/system_misc.h
>> @@ -58,4 +58,6 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
>>   
>>   #endif	/* __ASSEMBLY__ */
>>   
>> +int handle_guest_sea(unsigned long addr, unsigned int esr);
> Same remark here.
Same here.
>
>> +
>>   #endif	/* __ASM_SYSTEM_MISC_H */
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index f7372ce..ee96307 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -497,6 +497,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   {
>>   	struct siginfo info;
>> +	int ret = 0;
>>   
>>   	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
>>   		 fault_name(esr), esr, addr);
>> @@ -508,7 +509,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   	 */
>>   	if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>>   		nmi_enter();
>> -		ghes_notify_sea();
>> +		ret = ghes_notify_sea();
>>   		nmi_exit();
>>   	}
>>   
>> @@ -521,7 +522,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   		info.si_addr  = (void __user *)addr;
>>   	arm64_notify_die("", regs, &info, esr);
>>   
>> -	return 0;
>> +	return ret;
>>   }
>>   
>>   static const struct fault_info {
>> @@ -603,6 +604,20 @@ static const char *fault_name(unsigned int esr)
>>   }
>>   
>>   /*
>> + * Handle Synchronous External Aborts that occur in a guest kernel.
>> + */
>> +int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	int ret = -ENOENT;
>> +
>> +	if(IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>> +		ret = ghes_notify_sea();
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/*
>>    * Dispatch a data abort to the relevant handler.
>>    */
>>   asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 230b095..81eabc6 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -810,17 +810,18 @@ static int ghes_notify_sci(struct notifier_block *this,
>>   #ifdef CONFIG_ACPI_APEI_SEA
>>   static LIST_HEAD(ghes_sea);
>>   
>> -void ghes_notify_sea(void)
>> +int ghes_notify_sea(void)
>>   {
>>   	struct ghes *ghes;
>> +	int ret = -ENOENT;
>>   
>> -	/*
>> -	 * synchronize_rcu() will wait for nmi_exit(), so no need to
>> -	 * rcu_read_lock().
>> -	 */
>> +	rcu_read_lock();
>>   	list_for_each_entry_rcu(ghes, &ghes_sea, list) {
>> -		ghes_proc(ghes);
>> +		if(!ghes_proc(ghes))
>> +			ret = 0;
>>   	}
>> +	rcu_read_unlock();
>> +	return ret;
>>   }
>>   
>>   static void ghes_sea_add(struct ghes *ghes)
>> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
>> index 18bc935..2a727dc 100644
>> --- a/include/acpi/ghes.h
>> +++ b/include/acpi/ghes.h
>> @@ -99,6 +99,6 @@ static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data
>>   		gdata + 1;
>>   }
>>   
>> -void ghes_notify_sea(void);
>> +int ghes_notify_sea(void);
>>   
>>   #endif /* GHES_H */
>>
> Otherwise, the KVM changes look good to me. Assuming you fix the two
> nits above:
>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks!
Tyler

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

WARNING: multiple messages have this Message-ID (diff)
From: "Baicar, Tyler" <tbaicar@codeaurora.org>
To: Marc Zyngier <marc.zyngier@arm.com>,
	christoffer.dall@linaro.org, pbonzini@redhat.com,
	rkrcmar@redhat.com, linux@armlinux.org.uk,
	catalin.marinas@arm.com, will.deacon@arm.com, rjw@rjwysocki.net,
	lenb@kernel.org, matt@codeblueprint.co.uk,
	robert.moore@intel.com, lv.zheng@intel.com, nkaje@codeaurora.org,
	zjzhang@codeaurora.org, mark.rutland@arm.com,
	james.morse@arm.com, akpm@linux-foundation.org,
	eun.taik.lee@samsung.com, sandeepa.s.prabhu@gmail.com,
	labbott@redhat.com, shijie.huang@arm.com,
	rruigrok@codeaurora.org, paul.gortmaker@windriver.com,
	tn@semihalf.com, fu.wei@linaro.org, rostedt@goodmis.org,
	bristot@redhat.com, linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	linux-efi@vger.kernel.org, devel@acpica.org,
	Suzuki.Poulose@arm.com, punit.agrawal@arm.com, astone@redhat.com,
	harba@codeaurora.org, hanjun.guo@linaro.org,
	john.garry@huawei.com, shiju.jose@huawei.com, joe@perches.com
Subject: Re: [PATCH V13 10/10] arm/arm64: KVM: add guest SEA support
Date: Tue, 28 Mar 2017 10:35:22 -0600	[thread overview]
Message-ID: <ba39628f-f389-afe2-ea45-4b1e2de5c2e9@codeaurora.org> (raw)
In-Reply-To: <bb4b4608-85ba-fd20-53b1-c19d99019de1@arm.com>

Hello Marc,


On 3/24/2017 8:03 AM, Marc Zyngier wrote:
> On 21/03/17 22:47, Tyler Baicar wrote:
>> Currently external aborts are unsupported by the guest abort
>> handling. Add handling for SEAs so that the host kernel reports
>> SEAs which occur in the guest kernel.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> ---
>>   arch/arm/include/asm/kvm_arm.h       | 10 +++++++++
>>   arch/arm/include/asm/system_misc.h   |  5 +++++
>>   arch/arm/kvm/mmu.c                   | 41 ++++++++++++++++++++++++++++++------
>>   arch/arm64/include/asm/kvm_arm.h     | 10 +++++++++
>>   arch/arm64/include/asm/system_misc.h |  2 ++
>>   arch/arm64/mm/fault.c                | 19 +++++++++++++++--
>>   drivers/acpi/apei/ghes.c             | 13 ++++++------
>>   include/acpi/ghes.h                  |  2 +-
>>   8 files changed, 86 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
>> index a3f0b3d..ebf020b 100644
>> --- a/arch/arm/include/asm/kvm_arm.h
>> +++ b/arch/arm/include/asm/kvm_arm.h
>> @@ -187,6 +187,16 @@
>>   #define FSC_FAULT	(0x04)
>>   #define FSC_ACCESS	(0x08)
>>   #define FSC_PERM	(0x0c)
>> +#define FSC_SEA		(0x10)
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~0xf)
>> diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
>> index a3d61ad..ea45d94 100644
>> --- a/arch/arm/include/asm/system_misc.h
>> +++ b/arch/arm/include/asm/system_misc.h
>> @@ -24,4 +24,9 @@
>>   
>>   #endif /* !__ASSEMBLY__ */
>>   
>> +static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	return -1;
>> +}
>> +
> Shouldn't this be in the #ifndef __ASSEMBLY__ block? The assembler is
> definitely going to barf on that...
I will move this in the next patch set.
>>   #endif /* __ASM_ARM_SYSTEM_MISC_H */
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index 962616f..105b6ab 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -29,6 +29,7 @@
>>   #include <asm/kvm_asm.h>
>>   #include <asm/kvm_emulate.h>
>>   #include <asm/virt.h>
>> +#include <asm/system_misc.h>
>>   
>>   #include "trace.h"
>>   
>> @@ -1406,6 +1407,24 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>>   		kvm_set_pfn_accessed(pfn);
>>   }
>>   
>> +static bool is_abort_synchronous(unsigned long fault_status) {
>> +	switch (fault_status) {
>> +	case FSC_SEA:
>> +	case FSC_SEA_TTW0:
>> +	case FSC_SEA_TTW1:
>> +	case FSC_SEA_TTW2:
>> +	case FSC_SEA_TTW3:
>> +	case FSC_SECC:
>> +	case FSC_SECC_TTW0:
>> +	case FSC_SECC_TTW1:
>> +	case FSC_SECC_TTW2:
>> +	case FSC_SECC_TTW3:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>>   /**
>>    * kvm_handle_guest_abort - handles all 2nd stage aborts
>>    * @vcpu:	the VCPU pointer
>> @@ -1426,23 +1445,31 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>   	unsigned long hva;
>>   	bool is_iabt, write_fault, writable;
>>   	gfn_t gfn;
>> -	int ret, idx;
>> +	int ret, idx, sea_status = 1;
>> +
>> +	/* Check the stage-2 fault is trans. fault or write fault */
>> +	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>> +
>> +	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> +
>> +	/* The host kernel will handle the synchronous external abort. There
>> +	 * is no need to pass the error into the guest.
>> +	 */
>> +	if (is_abort_synchronous(fault_status))
>> +		sea_status = handle_guest_sea((unsigned long)fault_ipa,
>> +				    kvm_vcpu_get_hsr(vcpu));
>>   
>>   	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>> -	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) {
>> +	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu)) && sea_status) {
>>   		kvm_inject_vabt(vcpu);
>>   		return 1;
>>   	}
>>   
>> -	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> -
>>   	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
>>   			      kvm_vcpu_get_hfar(vcpu), fault_ipa);
>>   
>> -	/* Check the stage-2 fault is trans. fault or write fault */
>> -	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>>   	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
>> -	    fault_status != FSC_ACCESS) {
>> +	    fault_status != FSC_ACCESS && sea_status) {
>>   		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
>>   			kvm_vcpu_trap_get_class(vcpu),
>>   			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
>> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
>> index 6e99978..61d694c 100644
>> --- a/arch/arm64/include/asm/kvm_arm.h
>> +++ b/arch/arm64/include/asm/kvm_arm.h
>> @@ -204,6 +204,16 @@
>>   #define FSC_FAULT	ESR_ELx_FSC_FAULT
>>   #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
>>   #define FSC_PERM	ESR_ELx_FSC_PERM
>> +#define FSC_SEA		ESR_ELx_FSC_EXTABT
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~UL(0xf))
>> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
>> index bc81243..5b2cecd 100644
>> --- a/arch/arm64/include/asm/system_misc.h
>> +++ b/arch/arm64/include/asm/system_misc.h
>> @@ -58,4 +58,6 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
>>   
>>   #endif	/* __ASSEMBLY__ */
>>   
>> +int handle_guest_sea(unsigned long addr, unsigned int esr);
> Same remark here.
Same here.
>
>> +
>>   #endif	/* __ASM_SYSTEM_MISC_H */
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index f7372ce..ee96307 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -497,6 +497,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   {
>>   	struct siginfo info;
>> +	int ret = 0;
>>   
>>   	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
>>   		 fault_name(esr), esr, addr);
>> @@ -508,7 +509,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   	 */
>>   	if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>>   		nmi_enter();
>> -		ghes_notify_sea();
>> +		ret = ghes_notify_sea();
>>   		nmi_exit();
>>   	}
>>   
>> @@ -521,7 +522,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   		info.si_addr  = (void __user *)addr;
>>   	arm64_notify_die("", regs, &info, esr);
>>   
>> -	return 0;
>> +	return ret;
>>   }
>>   
>>   static const struct fault_info {
>> @@ -603,6 +604,20 @@ static const char *fault_name(unsigned int esr)
>>   }
>>   
>>   /*
>> + * Handle Synchronous External Aborts that occur in a guest kernel.
>> + */
>> +int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	int ret = -ENOENT;
>> +
>> +	if(IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>> +		ret = ghes_notify_sea();
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/*
>>    * Dispatch a data abort to the relevant handler.
>>    */
>>   asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 230b095..81eabc6 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -810,17 +810,18 @@ static int ghes_notify_sci(struct notifier_block *this,
>>   #ifdef CONFIG_ACPI_APEI_SEA
>>   static LIST_HEAD(ghes_sea);
>>   
>> -void ghes_notify_sea(void)
>> +int ghes_notify_sea(void)
>>   {
>>   	struct ghes *ghes;
>> +	int ret = -ENOENT;
>>   
>> -	/*
>> -	 * synchronize_rcu() will wait for nmi_exit(), so no need to
>> -	 * rcu_read_lock().
>> -	 */
>> +	rcu_read_lock();
>>   	list_for_each_entry_rcu(ghes, &ghes_sea, list) {
>> -		ghes_proc(ghes);
>> +		if(!ghes_proc(ghes))
>> +			ret = 0;
>>   	}
>> +	rcu_read_unlock();
>> +	return ret;
>>   }
>>   
>>   static void ghes_sea_add(struct ghes *ghes)
>> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
>> index 18bc935..2a727dc 100644
>> --- a/include/acpi/ghes.h
>> +++ b/include/acpi/ghes.h
>> @@ -99,6 +99,6 @@ static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data
>>   		gdata + 1;
>>   }
>>   
>> -void ghes_notify_sea(void);
>> +int ghes_notify_sea(void);
>>   
>>   #endif /* GHES_H */
>>
> Otherwise, the KVM changes look good to me. Assuming you fix the two
> nits above:
>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks!
Tyler

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

WARNING: multiple messages have this Message-ID (diff)
From: "Baicar, Tyler" <tbaicar@codeaurora.org>
To: Marc Zyngier <marc.zyngier@arm.com>,
	christoffer.dall@linaro.org, pbonzini@redhat.com,
	rkrcmar@redhat.com, linux@armlinux.org.uk,
	catalin.marinas@arm.com, will.deacon@arm.com, rjw@rjwysocki.net,
	lenb@kernel.org, matt@codeblueprint.co.uk,
	robert.moore@intel.com, lv.zheng@intel.com, nkaje@codeaurora.org,
	zjzhang@codeaurora.org, mark.rutland@arm.com,
	james.morse@arm.com, akpm@linux-foundation.org,
	eun.taik.lee@samsung.com, sandeepa.s.prabhu@gmail.com,
	labbott@redhat.com, shijie.huang@arm.com,
	rruigrok@codeaurora.org, paul.gortmaker@windriver.com,
	tn@semihalf.com, fu.wei@linaro.org, rostedt@goodmis.org,
	bristot@redhat.com, linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	linux-efi@vger.kernel.org, devel@acpica.org,
	Suzuki.Poulose@arm.com, punit.agrawal@arm.com, astone@redhat.com,
Subject: Re: [PATCH V13 10/10] arm/arm64: KVM: add guest SEA support
Date: Tue, 28 Mar 2017 10:35:22 -0600	[thread overview]
Message-ID: <ba39628f-f389-afe2-ea45-4b1e2de5c2e9@codeaurora.org> (raw)
In-Reply-To: <bb4b4608-85ba-fd20-53b1-c19d99019de1@arm.com>

Hello Marc,


On 3/24/2017 8:03 AM, Marc Zyngier wrote:
> On 21/03/17 22:47, Tyler Baicar wrote:
>> Currently external aborts are unsupported by the guest abort
>> handling. Add handling for SEAs so that the host kernel reports
>> SEAs which occur in the guest kernel.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> ---
>>   arch/arm/include/asm/kvm_arm.h       | 10 +++++++++
>>   arch/arm/include/asm/system_misc.h   |  5 +++++
>>   arch/arm/kvm/mmu.c                   | 41 ++++++++++++++++++++++++++++++------
>>   arch/arm64/include/asm/kvm_arm.h     | 10 +++++++++
>>   arch/arm64/include/asm/system_misc.h |  2 ++
>>   arch/arm64/mm/fault.c                | 19 +++++++++++++++--
>>   drivers/acpi/apei/ghes.c             | 13 ++++++------
>>   include/acpi/ghes.h                  |  2 +-
>>   8 files changed, 86 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
>> index a3f0b3d..ebf020b 100644
>> --- a/arch/arm/include/asm/kvm_arm.h
>> +++ b/arch/arm/include/asm/kvm_arm.h
>> @@ -187,6 +187,16 @@
>>   #define FSC_FAULT	(0x04)
>>   #define FSC_ACCESS	(0x08)
>>   #define FSC_PERM	(0x0c)
>> +#define FSC_SEA		(0x10)
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~0xf)
>> diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
>> index a3d61ad..ea45d94 100644
>> --- a/arch/arm/include/asm/system_misc.h
>> +++ b/arch/arm/include/asm/system_misc.h
>> @@ -24,4 +24,9 @@
>>   
>>   #endif /* !__ASSEMBLY__ */
>>   
>> +static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	return -1;
>> +}
>> +
> Shouldn't this be in the #ifndef __ASSEMBLY__ block? The assembler is
> definitely going to barf on that...
I will move this in the next patch set.
>>   #endif /* __ASM_ARM_SYSTEM_MISC_H */
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index 962616f..105b6ab 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -29,6 +29,7 @@
>>   #include <asm/kvm_asm.h>
>>   #include <asm/kvm_emulate.h>
>>   #include <asm/virt.h>
>> +#include <asm/system_misc.h>
>>   
>>   #include "trace.h"
>>   
>> @@ -1406,6 +1407,24 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>>   		kvm_set_pfn_accessed(pfn);
>>   }
>>   
>> +static bool is_abort_synchronous(unsigned long fault_status) {
>> +	switch (fault_status) {
>> +	case FSC_SEA:
>> +	case FSC_SEA_TTW0:
>> +	case FSC_SEA_TTW1:
>> +	case FSC_SEA_TTW2:
>> +	case FSC_SEA_TTW3:
>> +	case FSC_SECC:
>> +	case FSC_SECC_TTW0:
>> +	case FSC_SECC_TTW1:
>> +	case FSC_SECC_TTW2:
>> +	case FSC_SECC_TTW3:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>>   /**
>>    * kvm_handle_guest_abort - handles all 2nd stage aborts
>>    * @vcpu:	the VCPU pointer
>> @@ -1426,23 +1445,31 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>   	unsigned long hva;
>>   	bool is_iabt, write_fault, writable;
>>   	gfn_t gfn;
>> -	int ret, idx;
>> +	int ret, idx, sea_status = 1;
>> +
>> +	/* Check the stage-2 fault is trans. fault or write fault */
>> +	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>> +
>> +	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> +
>> +	/* The host kernel will handle the synchronous external abort. There
>> +	 * is no need to pass the error into the guest.
>> +	 */
>> +	if (is_abort_synchronous(fault_status))
>> +		sea_status = handle_guest_sea((unsigned long)fault_ipa,
>> +				    kvm_vcpu_get_hsr(vcpu));
>>   
>>   	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>> -	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) {
>> +	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu)) && sea_status) {
>>   		kvm_inject_vabt(vcpu);
>>   		return 1;
>>   	}
>>   
>> -	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> -
>>   	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
>>   			      kvm_vcpu_get_hfar(vcpu), fault_ipa);
>>   
>> -	/* Check the stage-2 fault is trans. fault or write fault */
>> -	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>>   	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
>> -	    fault_status != FSC_ACCESS) {
>> +	    fault_status != FSC_ACCESS && sea_status) {
>>   		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
>>   			kvm_vcpu_trap_get_class(vcpu),
>>   			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
>> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
>> index 6e99978..61d694c 100644
>> --- a/arch/arm64/include/asm/kvm_arm.h
>> +++ b/arch/arm64/include/asm/kvm_arm.h
>> @@ -204,6 +204,16 @@
>>   #define FSC_FAULT	ESR_ELx_FSC_FAULT
>>   #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
>>   #define FSC_PERM	ESR_ELx_FSC_PERM
>> +#define FSC_SEA		ESR_ELx_FSC_EXTABT
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~UL(0xf))
>> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
>> index bc81243..5b2cecd 100644
>> --- a/arch/arm64/include/asm/system_misc.h
>> +++ b/arch/arm64/include/asm/system_misc.h
>> @@ -58,4 +58,6 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
>>   
>>   #endif	/* __ASSEMBLY__ */
>>   
>> +int handle_guest_sea(unsigned long addr, unsigned int esr);
> Same remark here.
Same here.
>
>> +
>>   #endif	/* __ASM_SYSTEM_MISC_H */
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index f7372ce..ee96307 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -497,6 +497,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   {
>>   	struct siginfo info;
>> +	int ret = 0;
>>   
>>   	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
>>   		 fault_name(esr), esr, addr);
>> @@ -508,7 +509,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   	 */
>>   	if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>>   		nmi_enter();
>> -		ghes_notify_sea();
>> +		ret = ghes_notify_sea();
>>   		nmi_exit();
>>   	}
>>   
>> @@ -521,7 +522,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   		info.si_addr  = (void __user *)addr;
>>   	arm64_notify_die("", regs, &info, esr);
>>   
>> -	return 0;
>> +	return ret;
>>   }
>>   
>>   static const struct fault_info {
>> @@ -603,6 +604,20 @@ static const char *fault_name(unsigned int esr)
>>   }
>>   
>>   /*
>> + * Handle Synchronous External Aborts that occur in a guest kernel.
>> + */
>> +int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	int ret = -ENOENT;
>> +
>> +	if(IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>> +		ret = ghes_notify_sea();
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/*
>>    * Dispatch a data abort to the relevant handler.
>>    */
>>   asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 230b095..81eabc6 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -810,17 +810,18 @@ static int ghes_notify_sci(struct notifier_block *this,
>>   #ifdef CONFIG_ACPI_APEI_SEA
>>   static LIST_HEAD(ghes_sea);
>>   
>> -void ghes_notify_sea(void)
>> +int ghes_notify_sea(void)
>>   {
>>   	struct ghes *ghes;
>> +	int ret = -ENOENT;
>>   
>> -	/*
>> -	 * synchronize_rcu() will wait for nmi_exit(), so no need to
>> -	 * rcu_read_lock().
>> -	 */
>> +	rcu_read_lock();
>>   	list_for_each_entry_rcu(ghes, &ghes_sea, list) {
>> -		ghes_proc(ghes);
>> +		if(!ghes_proc(ghes))
>> +			ret = 0;
>>   	}
>> +	rcu_read_unlock();
>> +	return ret;
>>   }
>>   
>>   static void ghes_sea_add(struct ghes *ghes)
>> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
>> index 18bc935..2a727dc 100644
>> --- a/include/acpi/ghes.h
>> +++ b/include/acpi/ghes.h
>> @@ -99,6 +99,6 @@ static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data
>>   		gdata + 1;
>>   }
>>   
>> -void ghes_notify_sea(void);
>> +int ghes_notify_sea(void);
>>   
>>   #endif /* GHES_H */
>>
> Otherwise, the KVM changes look good to me. Assuming you fix the two
> nits above:
>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks!
Tyler

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

WARNING: multiple messages have this Message-ID (diff)
From: tbaicar@codeaurora.org (Baicar, Tyler)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V13 10/10] arm/arm64: KVM: add guest SEA support
Date: Tue, 28 Mar 2017 10:35:22 -0600	[thread overview]
Message-ID: <ba39628f-f389-afe2-ea45-4b1e2de5c2e9@codeaurora.org> (raw)
In-Reply-To: <bb4b4608-85ba-fd20-53b1-c19d99019de1@arm.com>

Hello Marc,


On 3/24/2017 8:03 AM, Marc Zyngier wrote:
> On 21/03/17 22:47, Tyler Baicar wrote:
>> Currently external aborts are unsupported by the guest abort
>> handling. Add handling for SEAs so that the host kernel reports
>> SEAs which occur in the guest kernel.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> ---
>>   arch/arm/include/asm/kvm_arm.h       | 10 +++++++++
>>   arch/arm/include/asm/system_misc.h   |  5 +++++
>>   arch/arm/kvm/mmu.c                   | 41 ++++++++++++++++++++++++++++++------
>>   arch/arm64/include/asm/kvm_arm.h     | 10 +++++++++
>>   arch/arm64/include/asm/system_misc.h |  2 ++
>>   arch/arm64/mm/fault.c                | 19 +++++++++++++++--
>>   drivers/acpi/apei/ghes.c             | 13 ++++++------
>>   include/acpi/ghes.h                  |  2 +-
>>   8 files changed, 86 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
>> index a3f0b3d..ebf020b 100644
>> --- a/arch/arm/include/asm/kvm_arm.h
>> +++ b/arch/arm/include/asm/kvm_arm.h
>> @@ -187,6 +187,16 @@
>>   #define FSC_FAULT	(0x04)
>>   #define FSC_ACCESS	(0x08)
>>   #define FSC_PERM	(0x0c)
>> +#define FSC_SEA		(0x10)
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~0xf)
>> diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
>> index a3d61ad..ea45d94 100644
>> --- a/arch/arm/include/asm/system_misc.h
>> +++ b/arch/arm/include/asm/system_misc.h
>> @@ -24,4 +24,9 @@
>>   
>>   #endif /* !__ASSEMBLY__ */
>>   
>> +static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	return -1;
>> +}
>> +
> Shouldn't this be in the #ifndef __ASSEMBLY__ block? The assembler is
> definitely going to barf on that...
I will move this in the next patch set.
>>   #endif /* __ASM_ARM_SYSTEM_MISC_H */
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index 962616f..105b6ab 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -29,6 +29,7 @@
>>   #include <asm/kvm_asm.h>
>>   #include <asm/kvm_emulate.h>
>>   #include <asm/virt.h>
>> +#include <asm/system_misc.h>
>>   
>>   #include "trace.h"
>>   
>> @@ -1406,6 +1407,24 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>>   		kvm_set_pfn_accessed(pfn);
>>   }
>>   
>> +static bool is_abort_synchronous(unsigned long fault_status) {
>> +	switch (fault_status) {
>> +	case FSC_SEA:
>> +	case FSC_SEA_TTW0:
>> +	case FSC_SEA_TTW1:
>> +	case FSC_SEA_TTW2:
>> +	case FSC_SEA_TTW3:
>> +	case FSC_SECC:
>> +	case FSC_SECC_TTW0:
>> +	case FSC_SECC_TTW1:
>> +	case FSC_SECC_TTW2:
>> +	case FSC_SECC_TTW3:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>>   /**
>>    * kvm_handle_guest_abort - handles all 2nd stage aborts
>>    * @vcpu:	the VCPU pointer
>> @@ -1426,23 +1445,31 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>   	unsigned long hva;
>>   	bool is_iabt, write_fault, writable;
>>   	gfn_t gfn;
>> -	int ret, idx;
>> +	int ret, idx, sea_status = 1;
>> +
>> +	/* Check the stage-2 fault is trans. fault or write fault */
>> +	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>> +
>> +	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> +
>> +	/* The host kernel will handle the synchronous external abort. There
>> +	 * is no need to pass the error into the guest.
>> +	 */
>> +	if (is_abort_synchronous(fault_status))
>> +		sea_status = handle_guest_sea((unsigned long)fault_ipa,
>> +				    kvm_vcpu_get_hsr(vcpu));
>>   
>>   	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>> -	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) {
>> +	if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu)) && sea_status) {
>>   		kvm_inject_vabt(vcpu);
>>   		return 1;
>>   	}
>>   
>> -	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>> -
>>   	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
>>   			      kvm_vcpu_get_hfar(vcpu), fault_ipa);
>>   
>> -	/* Check the stage-2 fault is trans. fault or write fault */
>> -	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
>>   	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
>> -	    fault_status != FSC_ACCESS) {
>> +	    fault_status != FSC_ACCESS && sea_status) {
>>   		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
>>   			kvm_vcpu_trap_get_class(vcpu),
>>   			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
>> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
>> index 6e99978..61d694c 100644
>> --- a/arch/arm64/include/asm/kvm_arm.h
>> +++ b/arch/arm64/include/asm/kvm_arm.h
>> @@ -204,6 +204,16 @@
>>   #define FSC_FAULT	ESR_ELx_FSC_FAULT
>>   #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
>>   #define FSC_PERM	ESR_ELx_FSC_PERM
>> +#define FSC_SEA		ESR_ELx_FSC_EXTABT
>> +#define FSC_SEA_TTW0	(0x14)
>> +#define FSC_SEA_TTW1	(0x15)
>> +#define FSC_SEA_TTW2	(0x16)
>> +#define FSC_SEA_TTW3	(0x17)
>> +#define FSC_SECC	(0x18)
>> +#define FSC_SECC_TTW0	(0x1c)
>> +#define FSC_SECC_TTW1	(0x1d)
>> +#define FSC_SECC_TTW2	(0x1e)
>> +#define FSC_SECC_TTW3	(0x1f)
>>   
>>   /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
>>   #define HPFAR_MASK	(~UL(0xf))
>> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
>> index bc81243..5b2cecd 100644
>> --- a/arch/arm64/include/asm/system_misc.h
>> +++ b/arch/arm64/include/asm/system_misc.h
>> @@ -58,4 +58,6 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
>>   
>>   #endif	/* __ASSEMBLY__ */
>>   
>> +int handle_guest_sea(unsigned long addr, unsigned int esr);
> Same remark here.
Same here.
>
>> +
>>   #endif	/* __ASM_SYSTEM_MISC_H */
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index f7372ce..ee96307 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -497,6 +497,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   {
>>   	struct siginfo info;
>> +	int ret = 0;
>>   
>>   	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
>>   		 fault_name(esr), esr, addr);
>> @@ -508,7 +509,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   	 */
>>   	if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>>   		nmi_enter();
>> -		ghes_notify_sea();
>> +		ret = ghes_notify_sea();
>>   		nmi_exit();
>>   	}
>>   
>> @@ -521,7 +522,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>>   		info.si_addr  = (void __user *)addr;
>>   	arm64_notify_die("", regs, &info, esr);
>>   
>> -	return 0;
>> +	return ret;
>>   }
>>   
>>   static const struct fault_info {
>> @@ -603,6 +604,20 @@ static const char *fault_name(unsigned int esr)
>>   }
>>   
>>   /*
>> + * Handle Synchronous External Aborts that occur in a guest kernel.
>> + */
>> +int handle_guest_sea(unsigned long addr, unsigned int esr)
>> +{
>> +	int ret = -ENOENT;
>> +
>> +	if(IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
>> +		ret = ghes_notify_sea();
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/*
>>    * Dispatch a data abort to the relevant handler.
>>    */
>>   asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 230b095..81eabc6 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -810,17 +810,18 @@ static int ghes_notify_sci(struct notifier_block *this,
>>   #ifdef CONFIG_ACPI_APEI_SEA
>>   static LIST_HEAD(ghes_sea);
>>   
>> -void ghes_notify_sea(void)
>> +int ghes_notify_sea(void)
>>   {
>>   	struct ghes *ghes;
>> +	int ret = -ENOENT;
>>   
>> -	/*
>> -	 * synchronize_rcu() will wait for nmi_exit(), so no need to
>> -	 * rcu_read_lock().
>> -	 */
>> +	rcu_read_lock();
>>   	list_for_each_entry_rcu(ghes, &ghes_sea, list) {
>> -		ghes_proc(ghes);
>> +		if(!ghes_proc(ghes))
>> +			ret = 0;
>>   	}
>> +	rcu_read_unlock();
>> +	return ret;
>>   }
>>   
>>   static void ghes_sea_add(struct ghes *ghes)
>> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
>> index 18bc935..2a727dc 100644
>> --- a/include/acpi/ghes.h
>> +++ b/include/acpi/ghes.h
>> @@ -99,6 +99,6 @@ static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data
>>   		gdata + 1;
>>   }
>>   
>> -void ghes_notify_sea(void);
>> +int ghes_notify_sea(void);
>>   
>>   #endif /* GHES_H */
>>
> Otherwise, the KVM changes look good to me. Assuming you fix the two
> nits above:
>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Thanks!
Tyler

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

  reply	other threads:[~2017-03-28 16:35 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-21 22:46 [PATCH V13 00/10] Add UEFI 2.6 and ACPI 6.1 updates for RAS on ARM64 Tyler Baicar
2017-03-21 22:46 ` Tyler Baicar
2017-03-21 22:46 ` Tyler Baicar
2017-03-21 22:46 ` [PATCH V13 01/10] acpi: apei: read ack upon ghes record consumption Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46 ` [PATCH V13 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46 ` [PATCH V13 03/10] efi: parse ARM processor error Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46 ` [PATCH V13 04/10] arm64: exception: handle Synchronous External Abort Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-21 22:46   ` Tyler Baicar
2017-03-23 17:02   ` Catalin Marinas
2017-03-23 17:02     ` Catalin Marinas
2017-03-23 17:02     ` Catalin Marinas
2017-03-21 22:47 ` [PATCH V13 05/10] acpi: apei: handle SEA notification type for ARMv8 Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-23 17:55   ` Catalin Marinas
2017-03-23 17:55     ` Catalin Marinas
2017-03-23 17:55     ` Catalin Marinas
2017-03-21 22:47 ` [PATCH V13 06/10] acpi: apei: panic OS with fatal error status block Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47 ` [PATCH V13 07/10] efi: print unrecognized CPER section Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47 ` [PATCH V13 08/10] ras: acpi / apei: generate trace event for " Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-23 18:44   ` Shiju Jose
2017-03-23 18:44     ` Shiju Jose
2017-03-21 22:47 ` [PATCH V13 09/10] trace, ras: add ARM processor error trace event Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-22  2:48   ` Xie XiuQi
2017-03-22  2:48     ` Xie XiuQi
2017-03-22  2:48     ` Xie XiuQi
2017-03-22  2:48     ` Xie XiuQi
2017-03-22  3:05     ` Baicar, Tyler
2017-03-22  3:05       ` Baicar, Tyler
2017-03-22  3:05       ` Baicar, Tyler
2017-03-22  3:05       ` Baicar, Tyler
     [not found]   ` <1490136425-4324-10-git-send-email-tbaicar-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-03-22  2:48     ` Xie XiuQi
2017-03-21 22:47 ` [PATCH V13 10/10] arm/arm64: KVM: add guest SEA support Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
2017-03-21 22:47   ` Tyler Baicar
     [not found]   ` <1490136425-4324-11-git-send-email-tbaicar-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-03-23 17:58     ` Catalin Marinas
2017-03-23 17:58       ` Catalin Marinas
2017-03-23 17:58       ` Catalin Marinas
2017-03-28  9:53     ` gengdongjiu
2017-03-24 14:03   ` Marc Zyngier
2017-03-24 14:03     ` Marc Zyngier
2017-03-24 14:03     ` Marc Zyngier
2017-03-28 16:35     ` Baicar, Tyler [this message]
2017-03-28 16:35       ` Baicar, Tyler
2017-03-28 16:35       ` Baicar, Tyler
2017-03-28 16:35       ` Baicar, Tyler
2017-03-24 16:01   ` Christoffer Dall
2017-03-24 16:01     ` Christoffer Dall
2017-03-24 16:01     ` Christoffer Dall
2017-03-28  4:19     ` gengdongjiu
2017-03-28  4:19       ` gengdongjiu
2017-03-28  4:19       ` gengdongjiu
2017-03-28  4:19       ` gengdongjiu
2017-03-28 16:44       ` Baicar, Tyler
2017-03-28 16:44         ` Baicar, Tyler
2017-03-28 16:44         ` Baicar, Tyler
2017-03-28 16:42     ` Baicar, Tyler
2017-03-28 16:42       ` Baicar, Tyler
2017-03-28 16:42       ` Baicar, Tyler
2017-03-28  9:53   ` gengdongjiu
2017-03-28  9:53     ` gengdongjiu
2017-03-28  9:53     ` gengdongjiu
2017-03-28  9:53     ` gengdongjiu
2017-03-28 16:44     ` Baicar, Tyler
2017-03-28 16:44       ` Baicar, Tyler
2017-03-28 16:44       ` Baicar, Tyler
2017-03-28 10:57   ` James Morse
2017-03-28 10:57     ` James Morse
2017-03-28 10:57     ` James Morse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ba39628f-f389-afe2-ea45-4b1e2de5c2e9@codeaurora.org \
    --to=tbaicar@codeaurora.org \
    --cc=Suzuki.Poulose@arm.com \
    --cc=akpm@linux-foundation.org \
    --cc=astone@redhat.com \
    --cc=bristot@redhat.com \
    --cc=catalin.marinas@arm.com \
    --cc=christoffer.dall@linaro.org \
    --cc=devel@acpica.org \
    --cc=eun.taik.lee@samsung.com \
    --cc=fu.wei@linaro.org \
    --cc=james.morse@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=labbott@redhat.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=lv.zheng@intel.com \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=matt@codeblueprint.co.uk \
    --cc=nkaje@codeaurora.org \
    --cc=paul.gortmaker@windriver.com \
    --cc=pbonzini@redhat.com \
    --cc=punit.agrawal@arm.com \
    --cc=rjw@rjwysocki.net \
    --cc=rkrcmar@redhat.com \
    --cc=robert.moore@intel.com \
    --cc=rostedt@goodmis.org \
    --cc=rruigrok@codeaurora.org \
    --cc=sandeepa.s.prabhu@gmail.com \
    --cc=shijie.huang@arm.com \
    --cc=tn@semihalf.com \
    --cc=will.deacon@arm.com \
    --cc=zjzhang@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.