From: David Gibson <david@gibson.dropbear.id.au>
To: "Cédric Le Goater" <clg@kaod.org>
Cc: Suraj Jitindar Singh <sjitindarsingh@gmail.com>,
qemu-ppc@nongnu.org, Greg Kurz <groug@kaod.org>,
Nicholas Piggin <npiggin@gmail.com>,
qemu-devel@nongnu.org
Subject: Re: [PATCH 4/7] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation
Date: Tue, 31 Mar 2020 12:13:10 +1100 [thread overview]
Message-ID: <20200331011310.GG47772@umbus.fritz.box> (raw)
In-Reply-To: <88580970-a739-b32f-528f-26c6aa81b598@kaod.org>
[-- Attachment #1: Type: text/plain, Size: 9811 bytes --]
On Mon, Mar 30, 2020 at 05:34:40PM +0200, Cédric Le Goater wrote:
> >>> + /* No valid pte or access denied due to protection */
> >>> + if (cause_excp) {
> >>> + ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
> >>> + }
> >>> + return 1;
> >>> + }
> >>> +
> >>> + ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, g_prot);
> >>> +
> >>> + return 0;
> >>> +}
> >>> +
> >>> +static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> >>> + uint64_t lpid, uint64_t pid, bool relocation,
> >>> + hwaddr *raddr, int *psizep, int *protp,
> >>> + bool cause_excp)
> >>> +{
> >>> + ppc_v3_pate_t pate;
> >>> + int psize, prot;
> >>> + hwaddr g_raddr;
> >>> +
> >>> + *psizep = INT_MAX;
> >>> + *protp = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> >>> +
> >>> + /* Get Process Table */
> >>> + if (cpu->vhyp && lpid == 0) {
> >>
> >> Current code doesn't check lpid == 0. Not sure to see what it's for...
> >
> > cpu->vhyp means a pseries machine, lpid == 0 means accessing quadrant3,
> > so it's the kernel.
>
> Sorry. I misread that. It would pid == 0 for the kernel.
>
> So yes, the test cpu->vhyp && lpid == 0 might be a bit overkill, given
> that lpid is always 0 when running under a QEMU pseries machine.
Overkill and conceptually incorrect. When in vhyp mode we're not
modelling the hypervisor part of the CPU, which means that really the
LPID doesn't exist, so we shouldn't be looking at it (though it will
always be 0 in practice).
>
>
> C.
>
> >
> >> especially env->spr[SPR_LPIDR] is always 0 with pseries machine types
> >> AFAICT... is it even possible to have lpid != 0 here ?
> >
> > When under PowerNV, SPR_LPIDR can be set, but not under pseries.
> >
> > C.
> >
> >>
> >>
> >> Rest LGTM.
> >>
> >>> + PPCVirtualHypervisorClass *vhc;
> >>> + vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> >>> + vhc->get_pate(cpu->vhyp, &pate);
> >>> + } else {
> >>> + if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
> >>> + if (cause_excp) {
> >>> + ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
> >>> + }
> >>> + return 1;
> >>> + }
> >>> + if (!validate_pate(cpu, lpid, &pate)) {
> >>> + if (cause_excp) {
> >>> + ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG);
> >>> + }
> >>> + return 1;
> >>> + }
> >>> + /* We don't support guest mode yet */
> >>> + if (lpid != 0) {
> >>> + error_report("PowerNV guest support Unimplemented");
> >>> + exit(1);
> >>> + }
> >>> + }
> >>> +
> >>> + /*
> >>> + * Perform process-scoped translation if relocation enabled.
> >>> + *
> >>> + * - Translates an effective address to a host real address in
> >>> + * quadrants 0 and 3 when HV=1.
> >>> + */
> >>> + if (relocation) {
> >>> + int ret = ppc_radix64_process_scoped_xlate(cpu, rwx, eaddr, lpid, pid,
> >>> + pate, &g_raddr, &prot,
> >>> + &psize, cause_excp);
> >>> + if (ret) {
> >>> + return ret;
> >>> + }
> >>> + *psizep = MIN(*psizep, psize);
> >>> + *protp &= prot;
> >>> + } else {
> >>> + g_raddr = eaddr & R_EADDR_MASK;
> >>> + }
> >>> +
> >>> + *raddr = g_raddr;
> >>> + return 0;
> >>> +}
> >>> +
> >>> int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> >>> int mmu_idx)
> >>> {
> >>> CPUState *cs = CPU(cpu);
> >>> CPUPPCState *env = &cpu->env;
> >>> - PPCVirtualHypervisorClass *vhc;
> >>> - hwaddr raddr, pte_addr;
> >>> - uint64_t lpid = 0, pid = 0, offset, size, prtbe0, pte;
> >>> - int page_size, prot, fault_cause = 0;
> >>> - ppc_v3_pate_t pate;
> >>> + uint64_t lpid = 0, pid = 0;
> >>> + int page_size, prot;
> >>> bool relocation;
> >>> + hwaddr raddr;
> >>>
> >>> assert(!(msr_hv && cpu->vhyp));
> >>> assert((rwx == 0) || (rwx == 1) || (rwx == 2));
> >>> @@ -268,48 +370,11 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> >>> return 1;
> >>> }
> >>>
> >>> - /* Get Process Table */
> >>> - if (cpu->vhyp) {
> >>> - vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> >>> - vhc->get_pate(cpu->vhyp, &pate);
> >>> - } else {
> >>> - if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
> >>> - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
> >>> - return 1;
> >>> - }
> >>> - if (!validate_pate(cpu, lpid, &pate)) {
> >>> - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG);
> >>> - }
> >>> - /* We don't support guest mode yet */
> >>> - if (lpid != 0) {
> >>> - error_report("PowerNV guest support Unimplemented");
> >>> - exit(1);
> >>> - }
> >>> - }
> >>> -
> >>> - /* Index Process Table by PID to Find Corresponding Process Table Entry */
> >>> - offset = pid * sizeof(struct prtb_entry);
> >>> - size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
> >>> - if (offset >= size) {
> >>> - /* offset exceeds size of the process table */
> >>> - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
> >>> + /* Translate eaddr to raddr (where raddr is addr qemu needs for access) */
> >>> + if (ppc_radix64_xlate(cpu, eaddr, rwx, lpid, pid, relocation, &raddr,
> >>> + &page_size, &prot, 1)) {
> >>> return 1;
> >>> }
> >>> - prtbe0 = ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset);
> >>> -
> >>> - /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
> >>> - page_size = PRTBE_R_GET_RTS(prtbe0);
> >>> - pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
> >>> - prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
> >>> - &raddr, &page_size, &fault_cause, &pte_addr);
> >>> - if (!pte || ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, &prot)) {
> >>> - /* Couldn't get pte or access denied due to protection */
> >>> - ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
> >>> - return 1;
> >>> - }
> >>> -
> >>> - /* Update Reference and Change Bits */
> >>> - ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, &prot);
> >>>
> >>> tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
> >>> prot, mmu_idx, 1UL << page_size);
> >>> @@ -318,16 +383,13 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> >>>
> >>> hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr)
> >>> {
> >>> - CPUState *cs = CPU(cpu);
> >>> CPUPPCState *env = &cpu->env;
> >>> - PPCVirtualHypervisorClass *vhc;
> >>> - hwaddr raddr, pte_addr;
> >>> - uint64_t lpid = 0, pid = 0, offset, size, prtbe0, pte;
> >>> - int page_size, fault_cause = 0;
> >>> - ppc_v3_pate_t pate;
> >>> + uint64_t lpid = 0, pid = 0;
> >>> + int psize, prot;
> >>> + hwaddr raddr;
> >>>
> >>> /* Handle Real Mode */
> >>> - if (msr_dr == 0) {
> >>> + if ((msr_dr == 0) && (msr_hv || (cpu->vhyp && lpid == 0))) {
> >>> /* In real mode top 4 effective addr bits (mostly) ignored */
> >>> return eaddr & 0x0FFFFFFFFFFFFFFFULL;
> >>> }
> >>> @@ -337,39 +399,8 @@ hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr)
> >>> return -1;
> >>> }
> >>>
> >>> - /* Get Process Table */
> >>> - if (cpu->vhyp) {
> >>> - vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> >>> - vhc->get_pate(cpu->vhyp, &pate);
> >>> - } else {
> >>> - if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
> >>> - return -1;
> >>> - }
> >>> - if (!validate_pate(cpu, lpid, &pate)) {
> >>> - return -1;
> >>> - }
> >>> - /* We don't support guest mode yet */
> >>> - if (lpid != 0) {
> >>> - error_report("PowerNV guest support Unimplemented");
> >>> - exit(1);
> >>> - }
> >>> - }
> >>> -
> >>> - /* Index Process Table by PID to Find Corresponding Process Table Entry */
> >>> - offset = pid * sizeof(struct prtb_entry);
> >>> - size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
> >>> - if (offset >= size) {
> >>> - /* offset exceeds size of the process table */
> >>> - return -1;
> >>> - }
> >>> - prtbe0 = ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset);
> >>> -
> >>> - /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
> >>> - page_size = PRTBE_R_GET_RTS(prtbe0);
> >>> - pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
> >>> - prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
> >>> - &raddr, &page_size, &fault_cause, &pte_addr);
> >>> - if (!pte) {
> >>> + if (ppc_radix64_xlate(cpu, eaddr, 0, lpid, pid, msr_dr, &raddr, &psize,
> >>> + &prot, 0)) {
> >>> return -1;
> >>> }
> >>>
> >>
> >
>
--
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2020-03-31 1:15 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-30 9:49 [PATCH 0/7] target/ppc: Add support for Radix partition-scoped translation Cédric Le Goater
2020-03-30 9:49 ` [PATCH 1/7] target/ppc: Enforce that the root page directory size must be at least 5 Cédric Le Goater
2020-03-30 10:45 ` Greg Kurz
2020-03-31 0:57 ` David Gibson
2020-03-30 9:49 ` [PATCH 2/7] target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault() Cédric Le Goater
2020-03-30 13:01 ` Greg Kurz
2020-03-31 0:58 ` David Gibson
2020-03-30 9:49 ` [PATCH 3/7] target/ppc: Assert if HV mode is set when running under a pseries machine Cédric Le Goater
2020-03-30 10:46 ` Greg Kurz
2020-03-31 0:59 ` David Gibson
2020-03-30 9:49 ` [PATCH 4/7] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation Cédric Le Goater
2020-03-30 14:18 ` Greg Kurz
2020-03-30 15:24 ` Cédric Le Goater
2020-03-30 15:34 ` Cédric Le Goater
2020-03-30 17:07 ` Greg Kurz
2020-03-31 1:13 ` David Gibson [this message]
2020-03-31 8:15 ` Cédric Le Goater
2020-03-30 9:49 ` [PATCH 5/7] target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation Cédric Le Goater
2020-03-30 17:00 ` Greg Kurz
2020-03-31 9:10 ` Cédric Le Goater
2020-03-31 9:49 ` Greg Kurz
2020-03-30 9:49 ` [PATCH 6/7] target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool Cédric Le Goater
2020-03-30 17:01 ` Greg Kurz
2020-03-31 8:22 ` Cédric Le Goater
2020-03-30 17:08 ` Greg Kurz
2020-03-30 9:49 ` [PATCH 7/7] target/ppc: Add support for Radix partition-scoped translation Cédric Le Goater
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=20200331011310.GG47772@umbus.fritz.box \
--to=david@gibson.dropbear.id.au \
--cc=clg@kaod.org \
--cc=groug@kaod.org \
--cc=npiggin@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=sjitindarsingh@gmail.com \
/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).