linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: catalin.marinas@arm.com (Catalin Marinas)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] kvm: arm64: Enable hardware updates of the Access Flag for Stage 2 page tables
Date: Mon, 9 May 2016 17:50:56 +0100	[thread overview]
Message-ID: <20160509165056.GC20598@e104818-lin.cambridge.arm.com> (raw)
In-Reply-To: <20160509153310.GA27623@cbox>

On Mon, May 09, 2016 at 05:33:10PM +0200, Christoffer Dall wrote:
> On Wed, Apr 13, 2016 at 05:57:37PM +0100, Catalin Marinas wrote:
> > The ARMv8.1 architecture extensions introduce support for hardware
> > updates of the access and dirty information in page table entries. With
> > VTCR_EL2.HA enabled (bit 21), when the CPU accesses an IPA with the
> > PTE_AF bit cleared in the stage 2 page table, instead of raising an
> > Access Flag fault to EL2 the CPU sets the actual page table entry bit
> > (10). To ensure that kernel modifications to the page table do not
> > inadvertently revert a bit set by hardware updates, certain Stage 2
> > software pte/pmd operations must be performed atomically.
> > 
> > The main user of the AF bit is the kvm_age_hva() mechanism. The
> > kvm_age_hva_handler() function performs a "test and clear young" action
> > on the pte/pmd. This needs to be atomic in respect of automatic hardware
> > updates of the AF bit. Since the AF bit is in the same position for both
> > Stage 1 and Stage 2, the patch reuses the existing
> > ptep_test_and_clear_young() functionality if
> > __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG is defined. Otherwise, the
> > existing pte_young/pte_mkold mechanism is preserved.
> > 
> > The kvm_set_s2pte_readonly() (and the corresponding pmd equivalent) have
> > to perform atomic modifications in order to avoid a race with updates of
> > the AF bit. The arm64 implementation has been re-written using
> > exclusives.
> > 
> > Currently, kvm_set_s2pte_writable() (and pmd equivalent) take a pointer
> > argument and modify the pte/pmd in place. However, these functions are
> > only used on local variables rather than actual page table entries, so
> > it makes more sense to follow the pte_mkwrite() approach for stage 1
> > attributes. The change to kvm_s2pte_mkwrite() makes it clear that these
> > functions do not modify the actual page table entries.
> 
> so if one CPU takes a permission fault and is in the process of updating
> the page table, what prevents another CPU from setting the access flag
> (on a read, done by HW) on that entry between us reading the old pte and
> replacing it with the new pte?

There isn't anything that would prevent this. However, as in the stage 1
scenarios, explicitly writing a PTE as a result of a permission fault
should also mark the entry as accessed (young, either as the default
protection in PROT_DEFAULT or explicitly via pte_mkyoung).

> Don't we loose the AF information in that case too?

Since the hardware never clears the AF bit automatically, there is no
information to lose in this race as long as the kvm_set_s2pte_writable()
sets the AF bit. AFAICT, the PAGE_S2 and PAGE_S2_DEVICE definitions
already use PROT_DEFAULT which has the AF bit set.

> >  static inline void kvm_set_s2pte_readonly(pte_t *pte)
> >  {
> > -	pte_val(*pte) = (pte_val(*pte) & ~PTE_S2_RDWR) | PTE_S2_RDONLY;
> > +	pteval_t pteval;
> > +	unsigned long tmp;
> > +
> > +	asm volatile("//	kvm_set_s2pte_readonly\n"
> > +	"	prfm	pstl1strm, %2\n"
> > +	"1:	ldxr	%0, %2\n"
> > +	"	and	%0, %0, %3		// clear PTE_S2_RDWR\n"
> > +	"	orr	%0, %0, %4		// set PTE_S2_RDONLY\n"
> > +	"	stxr	%w1, %0, %2\n"
> > +	"	cbnz	%w1, 1b\n"
> > +	: "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*pte))
> 
> so the +Q means "pass the memory address of the value and by the way the
> content, not the address itself, can be updated by the assembly code" ?

Yes. I think "info gcc" isn't clear enough on this constraint (at least
to me) but that's something we learnt from the tools guys in the early
days of the aarch64 kernel port.

-- 
Catalin

  reply	other threads:[~2016-05-09 16:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-13 16:57 [PATCH] kvm: arm64: Enable hardware updates of the Access Flag for Stage 2 page tables Catalin Marinas
2016-05-05 17:33 ` Marc Zyngier
2016-05-09 15:33 ` Christoffer Dall
2016-05-09 16:50   ` Catalin Marinas [this message]
2016-05-09 20:21     ` Christoffer Dall

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=20160509165056.GC20598@e104818-lin.cambridge.arm.com \
    --to=catalin.marinas@arm.com \
    --cc=linux-arm-kernel@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).