162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright IBM Corporation, 2015
362306a36Sopenharmony_ci * Author Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify it
662306a36Sopenharmony_ci * under the terms of version 2 of the GNU Lesser General Public License
762306a36Sopenharmony_ci * as published by the Free Software Foundation.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * This program is distributed in the hope that it would be useful, but
1062306a36Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
1162306a36Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/mm.h>
1662306a36Sopenharmony_ci#include <asm/machdep.h>
1762306a36Sopenharmony_ci#include <asm/mmu.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "internal.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * Return true, if the entry has a slot value which
2362306a36Sopenharmony_ci * the software considers as invalid.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_cistatic inline bool hpte_soft_invalid(unsigned long hidx)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	return ((hidx & 0xfUL) == 0xfUL);
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci * index from 0 - 15
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_cibool __rpte_sub_valid(real_pte_t rpte, unsigned long index)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	return !(hpte_soft_invalid(__rpte_to_hidx(rpte, index)));
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciint __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
3962306a36Sopenharmony_ci		   pte_t *ptep, unsigned long trap, unsigned long flags,
4062306a36Sopenharmony_ci		   int ssize, int subpg_prot)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	real_pte_t rpte;
4362306a36Sopenharmony_ci	unsigned long hpte_group;
4462306a36Sopenharmony_ci	unsigned int subpg_index;
4562306a36Sopenharmony_ci	unsigned long rflags, pa;
4662306a36Sopenharmony_ci	unsigned long old_pte, new_pte, subpg_pte;
4762306a36Sopenharmony_ci	unsigned long vpn, hash, slot, gslot;
4862306a36Sopenharmony_ci	unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/*
5162306a36Sopenharmony_ci	 * atomically mark the linux large page PTE busy and dirty
5262306a36Sopenharmony_ci	 */
5362306a36Sopenharmony_ci	do {
5462306a36Sopenharmony_ci		pte_t pte = READ_ONCE(*ptep);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci		old_pte = pte_val(pte);
5762306a36Sopenharmony_ci		/* If PTE busy, retry the access */
5862306a36Sopenharmony_ci		if (unlikely(old_pte & H_PAGE_BUSY))
5962306a36Sopenharmony_ci			return 0;
6062306a36Sopenharmony_ci		/* If PTE permissions don't match, take page fault */
6162306a36Sopenharmony_ci		if (unlikely(!check_pte_access(access, old_pte)))
6262306a36Sopenharmony_ci			return 1;
6362306a36Sopenharmony_ci		/*
6462306a36Sopenharmony_ci		 * Try to lock the PTE, add ACCESSED and DIRTY if it was
6562306a36Sopenharmony_ci		 * a write access. Since this is 4K insert of 64K page size
6662306a36Sopenharmony_ci		 * also add H_PAGE_COMBO
6762306a36Sopenharmony_ci		 */
6862306a36Sopenharmony_ci		new_pte = old_pte | H_PAGE_BUSY | _PAGE_ACCESSED | H_PAGE_COMBO;
6962306a36Sopenharmony_ci		if (access & _PAGE_WRITE)
7062306a36Sopenharmony_ci			new_pte |= _PAGE_DIRTY;
7162306a36Sopenharmony_ci	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	/*
7462306a36Sopenharmony_ci	 * Handle the subpage protection bits
7562306a36Sopenharmony_ci	 */
7662306a36Sopenharmony_ci	subpg_pte = new_pte & ~subpg_prot;
7762306a36Sopenharmony_ci	rflags = htab_convert_pte_flags(subpg_pte, flags);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
8062306a36Sopenharmony_ci	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci		/*
8362306a36Sopenharmony_ci		 * No CPU has hugepages but lacks no execute, so we
8462306a36Sopenharmony_ci		 * don't need to worry about that case
8562306a36Sopenharmony_ci		 */
8662306a36Sopenharmony_ci		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
8762306a36Sopenharmony_ci	}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	subpg_index = (ea & (PAGE_SIZE - 1)) >> shift;
9062306a36Sopenharmony_ci	vpn  = hpt_vpn(ea, vsid, ssize);
9162306a36Sopenharmony_ci	rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
9262306a36Sopenharmony_ci	/*
9362306a36Sopenharmony_ci	 *None of the sub 4k page is hashed
9462306a36Sopenharmony_ci	 */
9562306a36Sopenharmony_ci	if (!(old_pte & H_PAGE_HASHPTE))
9662306a36Sopenharmony_ci		goto htab_insert_hpte;
9762306a36Sopenharmony_ci	/*
9862306a36Sopenharmony_ci	 * Check if the pte was already inserted into the hash table
9962306a36Sopenharmony_ci	 * as a 64k HW page, and invalidate the 64k HPTE if so.
10062306a36Sopenharmony_ci	 */
10162306a36Sopenharmony_ci	if (!(old_pte & H_PAGE_COMBO)) {
10262306a36Sopenharmony_ci		flush_hash_page(vpn, rpte, MMU_PAGE_64K, ssize, flags);
10362306a36Sopenharmony_ci		/*
10462306a36Sopenharmony_ci		 * clear the old slot details from the old and new pte.
10562306a36Sopenharmony_ci		 * On hash insert failure we use old pte value and we don't
10662306a36Sopenharmony_ci		 * want slot information there if we have a insert failure.
10762306a36Sopenharmony_ci		 */
10862306a36Sopenharmony_ci		old_pte &= ~H_PAGE_HASHPTE;
10962306a36Sopenharmony_ci		new_pte &= ~H_PAGE_HASHPTE;
11062306a36Sopenharmony_ci		goto htab_insert_hpte;
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci	/*
11362306a36Sopenharmony_ci	 * Check for sub page valid and update
11462306a36Sopenharmony_ci	 */
11562306a36Sopenharmony_ci	if (__rpte_sub_valid(rpte, subpg_index)) {
11662306a36Sopenharmony_ci		int ret;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte,
11962306a36Sopenharmony_ci					   subpg_index);
12062306a36Sopenharmony_ci		ret = mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn,
12162306a36Sopenharmony_ci						 MMU_PAGE_4K, MMU_PAGE_4K,
12262306a36Sopenharmony_ci						 ssize, flags);
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci		/*
12562306a36Sopenharmony_ci		 * If we failed because typically the HPTE wasn't really here
12662306a36Sopenharmony_ci		 * we try an insertion.
12762306a36Sopenharmony_ci		 */
12862306a36Sopenharmony_ci		if (ret == -1)
12962306a36Sopenharmony_ci			goto htab_insert_hpte;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		*ptep = __pte(new_pte & ~H_PAGE_BUSY);
13262306a36Sopenharmony_ci		return 0;
13362306a36Sopenharmony_ci	}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cihtab_insert_hpte:
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	/*
13862306a36Sopenharmony_ci	 * Initialize all hidx entries to invalid value, the first time
13962306a36Sopenharmony_ci	 * the PTE is about to allocate a 4K HPTE.
14062306a36Sopenharmony_ci	 */
14162306a36Sopenharmony_ci	if (!(old_pte & H_PAGE_COMBO))
14262306a36Sopenharmony_ci		rpte.hidx = INVALID_RPTE_HIDX;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	/*
14562306a36Sopenharmony_ci	 * handle H_PAGE_4K_PFN case
14662306a36Sopenharmony_ci	 */
14762306a36Sopenharmony_ci	if (old_pte & H_PAGE_4K_PFN) {
14862306a36Sopenharmony_ci		/*
14962306a36Sopenharmony_ci		 * All the sub 4k page have the same
15062306a36Sopenharmony_ci		 * physical address.
15162306a36Sopenharmony_ci		 */
15262306a36Sopenharmony_ci		pa = pte_pfn(__pte(old_pte)) << HW_PAGE_SHIFT;
15362306a36Sopenharmony_ci	} else {
15462306a36Sopenharmony_ci		pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
15562306a36Sopenharmony_ci		pa += (subpg_index << shift);
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci	hash = hpt_hash(vpn, shift, ssize);
15862306a36Sopenharmony_cirepeat:
15962306a36Sopenharmony_ci	hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	/* Insert into the hash table, primary slot */
16262306a36Sopenharmony_ci	slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa, rflags, 0,
16362306a36Sopenharmony_ci					MMU_PAGE_4K, MMU_PAGE_4K, ssize);
16462306a36Sopenharmony_ci	/*
16562306a36Sopenharmony_ci	 * Primary is full, try the secondary
16662306a36Sopenharmony_ci	 */
16762306a36Sopenharmony_ci	if (unlikely(slot == -1)) {
16862306a36Sopenharmony_ci		bool soft_invalid;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci		hpte_group = (~hash & htab_hash_mask) * HPTES_PER_GROUP;
17162306a36Sopenharmony_ci		slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa,
17262306a36Sopenharmony_ci						rflags, HPTE_V_SECONDARY,
17362306a36Sopenharmony_ci						MMU_PAGE_4K, MMU_PAGE_4K,
17462306a36Sopenharmony_ci						ssize);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci		soft_invalid = hpte_soft_invalid(slot);
17762306a36Sopenharmony_ci		if (unlikely(soft_invalid)) {
17862306a36Sopenharmony_ci			/*
17962306a36Sopenharmony_ci			 * We got a valid slot from a hardware point of view.
18062306a36Sopenharmony_ci			 * but we cannot use it, because we use this special
18162306a36Sopenharmony_ci			 * value; as defined by hpte_soft_invalid(), to track
18262306a36Sopenharmony_ci			 * invalid slots. We cannot use it. So invalidate it.
18362306a36Sopenharmony_ci			 */
18462306a36Sopenharmony_ci			gslot = slot & _PTEIDX_GROUP_IX;
18562306a36Sopenharmony_ci			mmu_hash_ops.hpte_invalidate(hpte_group + gslot, vpn,
18662306a36Sopenharmony_ci						     MMU_PAGE_4K, MMU_PAGE_4K,
18762306a36Sopenharmony_ci						     ssize, 0);
18862306a36Sopenharmony_ci		}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci		if (unlikely(slot == -1 || soft_invalid)) {
19162306a36Sopenharmony_ci			/*
19262306a36Sopenharmony_ci			 * For soft invalid slot, let's ensure that we release a
19362306a36Sopenharmony_ci			 * slot from the primary, with the hope that we will
19462306a36Sopenharmony_ci			 * acquire that slot next time we try. This will ensure
19562306a36Sopenharmony_ci			 * that we do not get the same soft-invalid slot.
19662306a36Sopenharmony_ci			 */
19762306a36Sopenharmony_ci			if (soft_invalid || (mftb() & 0x1))
19862306a36Sopenharmony_ci				hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci			mmu_hash_ops.hpte_remove(hpte_group);
20162306a36Sopenharmony_ci			/*
20262306a36Sopenharmony_ci			 * FIXME!! Should be try the group from which we removed ?
20362306a36Sopenharmony_ci			 */
20462306a36Sopenharmony_ci			goto repeat;
20562306a36Sopenharmony_ci		}
20662306a36Sopenharmony_ci	}
20762306a36Sopenharmony_ci	/*
20862306a36Sopenharmony_ci	 * Hypervisor failure. Restore old pte and return -1
20962306a36Sopenharmony_ci	 * similar to __hash_page_*
21062306a36Sopenharmony_ci	 */
21162306a36Sopenharmony_ci	if (unlikely(slot == -2)) {
21262306a36Sopenharmony_ci		*ptep = __pte(old_pte);
21362306a36Sopenharmony_ci		hash_failure_debug(ea, access, vsid, trap, ssize,
21462306a36Sopenharmony_ci				   MMU_PAGE_4K, MMU_PAGE_4K, old_pte);
21562306a36Sopenharmony_ci		return -1;
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot, PTRS_PER_PTE);
21962306a36Sopenharmony_ci	new_pte |= H_PAGE_HASHPTE;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	if (stress_hpt())
22262306a36Sopenharmony_ci		hpt_do_stress(ea, hpte_group);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	*ptep = __pte(new_pte & ~H_PAGE_BUSY);
22562306a36Sopenharmony_ci	return 0;
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciint __hash_page_64K(unsigned long ea, unsigned long access,
22962306a36Sopenharmony_ci		    unsigned long vsid, pte_t *ptep, unsigned long trap,
23062306a36Sopenharmony_ci		    unsigned long flags, int ssize)
23162306a36Sopenharmony_ci{
23262306a36Sopenharmony_ci	real_pte_t rpte;
23362306a36Sopenharmony_ci	unsigned long hpte_group;
23462306a36Sopenharmony_ci	unsigned long rflags, pa;
23562306a36Sopenharmony_ci	unsigned long old_pte, new_pte;
23662306a36Sopenharmony_ci	unsigned long vpn, hash, slot;
23762306a36Sopenharmony_ci	unsigned long shift = mmu_psize_defs[MMU_PAGE_64K].shift;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	/*
24062306a36Sopenharmony_ci	 * atomically mark the linux large page PTE busy and dirty
24162306a36Sopenharmony_ci	 */
24262306a36Sopenharmony_ci	do {
24362306a36Sopenharmony_ci		pte_t pte = READ_ONCE(*ptep);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci		old_pte = pte_val(pte);
24662306a36Sopenharmony_ci		/* If PTE busy, retry the access */
24762306a36Sopenharmony_ci		if (unlikely(old_pte & H_PAGE_BUSY))
24862306a36Sopenharmony_ci			return 0;
24962306a36Sopenharmony_ci		/* If PTE permissions don't match, take page fault */
25062306a36Sopenharmony_ci		if (unlikely(!check_pte_access(access, old_pte)))
25162306a36Sopenharmony_ci			return 1;
25262306a36Sopenharmony_ci		/*
25362306a36Sopenharmony_ci		 * Check if PTE has the cache-inhibit bit set
25462306a36Sopenharmony_ci		 * If so, bail out and refault as a 4k page
25562306a36Sopenharmony_ci		 */
25662306a36Sopenharmony_ci		if (!mmu_has_feature(MMU_FTR_CI_LARGE_PAGE) &&
25762306a36Sopenharmony_ci		    unlikely(pte_ci(pte)))
25862306a36Sopenharmony_ci			return 0;
25962306a36Sopenharmony_ci		/*
26062306a36Sopenharmony_ci		 * Try to lock the PTE, add ACCESSED and DIRTY if it was
26162306a36Sopenharmony_ci		 * a write access.
26262306a36Sopenharmony_ci		 */
26362306a36Sopenharmony_ci		new_pte = old_pte | H_PAGE_BUSY | _PAGE_ACCESSED;
26462306a36Sopenharmony_ci		if (access & _PAGE_WRITE)
26562306a36Sopenharmony_ci			new_pte |= _PAGE_DIRTY;
26662306a36Sopenharmony_ci	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	rflags = htab_convert_pte_flags(new_pte, flags);
26962306a36Sopenharmony_ci	rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
27262306a36Sopenharmony_ci	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
27362306a36Sopenharmony_ci		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	vpn  = hpt_vpn(ea, vsid, ssize);
27662306a36Sopenharmony_ci	if (unlikely(old_pte & H_PAGE_HASHPTE)) {
27762306a36Sopenharmony_ci		unsigned long gslot;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci		/*
28062306a36Sopenharmony_ci		 * There MIGHT be an HPTE for this pte
28162306a36Sopenharmony_ci		 */
28262306a36Sopenharmony_ci		gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte, 0);
28362306a36Sopenharmony_ci		if (mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn, MMU_PAGE_64K,
28462306a36Sopenharmony_ci					       MMU_PAGE_64K, ssize,
28562306a36Sopenharmony_ci					       flags) == -1)
28662306a36Sopenharmony_ci			old_pte &= ~_PAGE_HPTEFLAGS;
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	if (likely(!(old_pte & H_PAGE_HASHPTE))) {
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci		pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
29262306a36Sopenharmony_ci		hash = hpt_hash(vpn, shift, ssize);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cirepeat:
29562306a36Sopenharmony_ci		hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci		/* Insert into the hash table, primary slot */
29862306a36Sopenharmony_ci		slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa, rflags, 0,
29962306a36Sopenharmony_ci						MMU_PAGE_64K, MMU_PAGE_64K,
30062306a36Sopenharmony_ci						ssize);
30162306a36Sopenharmony_ci		/*
30262306a36Sopenharmony_ci		 * Primary is full, try the secondary
30362306a36Sopenharmony_ci		 */
30462306a36Sopenharmony_ci		if (unlikely(slot == -1)) {
30562306a36Sopenharmony_ci			hpte_group = (~hash & htab_hash_mask) * HPTES_PER_GROUP;
30662306a36Sopenharmony_ci			slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa,
30762306a36Sopenharmony_ci							rflags,
30862306a36Sopenharmony_ci							HPTE_V_SECONDARY,
30962306a36Sopenharmony_ci							MMU_PAGE_64K,
31062306a36Sopenharmony_ci							MMU_PAGE_64K, ssize);
31162306a36Sopenharmony_ci			if (slot == -1) {
31262306a36Sopenharmony_ci				if (mftb() & 0x1)
31362306a36Sopenharmony_ci					hpte_group = (hash & htab_hash_mask) *
31462306a36Sopenharmony_ci							HPTES_PER_GROUP;
31562306a36Sopenharmony_ci				mmu_hash_ops.hpte_remove(hpte_group);
31662306a36Sopenharmony_ci				/*
31762306a36Sopenharmony_ci				 * FIXME!! Should be try the group from which we removed ?
31862306a36Sopenharmony_ci				 */
31962306a36Sopenharmony_ci				goto repeat;
32062306a36Sopenharmony_ci			}
32162306a36Sopenharmony_ci		}
32262306a36Sopenharmony_ci		/*
32362306a36Sopenharmony_ci		 * Hypervisor failure. Restore old pte and return -1
32462306a36Sopenharmony_ci		 * similar to __hash_page_*
32562306a36Sopenharmony_ci		 */
32662306a36Sopenharmony_ci		if (unlikely(slot == -2)) {
32762306a36Sopenharmony_ci			*ptep = __pte(old_pte);
32862306a36Sopenharmony_ci			hash_failure_debug(ea, access, vsid, trap, ssize,
32962306a36Sopenharmony_ci					   MMU_PAGE_64K, MMU_PAGE_64K, old_pte);
33062306a36Sopenharmony_ci			return -1;
33162306a36Sopenharmony_ci		}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci		new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
33462306a36Sopenharmony_ci		new_pte |= pte_set_hidx(ptep, rpte, 0, slot, PTRS_PER_PTE);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		if (stress_hpt())
33762306a36Sopenharmony_ci			hpt_do_stress(ea, hpte_group);
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	*ptep = __pte(new_pte & ~H_PAGE_BUSY);
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	return 0;
34362306a36Sopenharmony_ci}
344