Skip to content

Commit 44a83b0

Browse files
committed
Merge: KVM: Fix two memory management related problems on s390x
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1128 JIRA: https://issues.redhat.com/browse/RHEL-92226 JIRA: https://issues.redhat.com/browse/RHEL-58218 Fix a call trace that can happen with the debug kernel on s390x when starting a nested guest, and fix a problem that occurs when backing the memory of a KVM guest with real files. Note: I've included some selftest patches at the beginning of the series to be able to cherry-pick the other patches cleanly. These selftest patches at the beginning of the patch series show up as having conflicts in "revumatic", but that's only due to a rename of a subfolder from "s390x" to "s390", the changes themselves are clean. Resolves: RHEL-92226 Resolves: RHEL-58218 Signed-off-by: Thomas Huth <thuth@redhat.com> Approved-by: Rafael Aquini <raquini@redhat.com> Approved-by: Cornelia Huck <cohuck@redhat.com> Merged-by: Julio Faracco <jfaracco@redhat.com>
2 parents 561e0ac + ab48fed commit 44a83b0

File tree

21 files changed

+1254
-854
lines changed

21 files changed

+1254
-854
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ fetch) is injected in the guest.
14231423
S390:
14241424
^^^^^
14251425

1426-
Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set.
1426+
Returns -EINVAL or -EEXIST if the VM has the KVM_VM_S390_UCONTROL flag set.
14271427
Returns -EINVAL if called on a protected VM.
14281428

14291429
4.36 KVM_SET_TSS_ADDR

arch/s390/include/asm/gmap.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
/**
2424
* struct gmap_struct - guest address space
2525
* @list: list head for the mm->context gmap list
26-
* @crst_list: list of all crst tables used in the guest address space
2726
* @mm: pointer to the parent mm_struct
2827
* @guest_to_host: radix tree with guest to host address translation
2928
* @host_to_guest: radix tree with pointer to segment table entries
@@ -35,7 +34,6 @@
3534
* @guest_handle: protected virtual machine handle for the ultravisor
3635
* @host_to_rmap: radix tree with gmap_rmap lists
3736
* @children: list of shadow gmap structures
38-
* @pt_list: list of all page tables used in the shadow guest address space
3937
* @shadow_lock: spinlock to protect the shadow gmap list
4038
* @parent: pointer to the parent gmap for shadow guest address spaces
4139
* @orig_asce: ASCE for which the shadow page table has been created
@@ -45,7 +43,6 @@
4543
*/
4644
struct gmap {
4745
struct list_head list;
48-
struct list_head crst_list;
4946
struct mm_struct *mm;
5047
struct radix_tree_root guest_to_host;
5148
struct radix_tree_root host_to_guest;
@@ -61,7 +58,6 @@ struct gmap {
6158
/* Additional data for shadow guest address spaces */
6259
struct radix_tree_root host_to_rmap;
6360
struct list_head children;
64-
struct list_head pt_list;
6561
spinlock_t shadow_lock;
6662
struct gmap *parent;
6763
unsigned long orig_asce;
@@ -106,23 +102,21 @@ struct gmap *gmap_create(struct mm_struct *mm, unsigned long limit);
106102
void gmap_remove(struct gmap *gmap);
107103
struct gmap *gmap_get(struct gmap *gmap);
108104
void gmap_put(struct gmap *gmap);
105+
void gmap_free(struct gmap *gmap);
106+
struct gmap *gmap_alloc(unsigned long limit);
109107

110108
int gmap_map_segment(struct gmap *gmap, unsigned long from,
111109
unsigned long to, unsigned long len);
112110
int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
113111
unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
114-
unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
115112
int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
116-
int gmap_fault(struct gmap *, unsigned long gaddr, unsigned int fault_flags);
117113
void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
118114
void __gmap_zap(struct gmap *, unsigned long gaddr);
119115
void gmap_unlink(struct mm_struct *, unsigned long *table, unsigned long vmaddr);
120116

121117
int gmap_read_table(struct gmap *gmap, unsigned long gaddr, unsigned long *val);
122118

123-
struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce,
124-
int edat_level);
125-
int gmap_shadow_valid(struct gmap *sg, unsigned long asce, int edat_level);
119+
void gmap_unshadow(struct gmap *sg);
126120
int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t,
127121
int fake);
128122
int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t,
@@ -131,24 +125,21 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt,
131125
int fake);
132126
int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
133127
int fake);
134-
int gmap_shadow_pgt_lookup(struct gmap *sg, unsigned long saddr,
135-
unsigned long *pgt, int *dat_protection, int *fake);
136128
int gmap_shadow_page(struct gmap *sg, unsigned long saddr, pte_t pte);
137129

138130
void gmap_register_pte_notifier(struct gmap_notifier *);
139131
void gmap_unregister_pte_notifier(struct gmap_notifier *);
140132

141-
int gmap_mprotect_notify(struct gmap *, unsigned long start,
142-
unsigned long len, int prot);
133+
int gmap_protect_one(struct gmap *gmap, unsigned long gaddr, int prot, unsigned long bits);
143134

144135
void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
145136
unsigned long gaddr, unsigned long vmaddr);
146137
int s390_disable_cow_sharing(void);
147-
void s390_unlist_old_asce(struct gmap *gmap);
148138
int s390_replace_asce(struct gmap *gmap);
149139
void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns);
150140
int __s390_uv_destroy_range(struct mm_struct *mm, unsigned long start,
151141
unsigned long end, bool interruptible);
142+
unsigned long *gmap_table_walk(struct gmap *gmap, unsigned long gaddr, int level);
152143

153144
/**
154145
* s390_uv_destroy_range - Destroy a range of pages in the given mm.

arch/s390/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#define KVM_S390_ESCA_CPU_SLOTS 248
3131
#define KVM_MAX_VCPUS 255
3232

33+
#define KVM_INTERNAL_MEM_SLOTS 1
34+
3335
/*
3436
* These seem to be used for allocating ->chip in the routing table, which we
3537
* don't use. 1 is as small as we can get to reduce the needed memory. If we

arch/s390/include/asm/pgtable.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,10 @@ static inline int is_module_addr(void *addr)
419419
#define PGSTE_HC_BIT 0x0020000000000000UL
420420
#define PGSTE_GR_BIT 0x0004000000000000UL
421421
#define PGSTE_GC_BIT 0x0002000000000000UL
422-
#define PGSTE_UC_BIT 0x0000800000000000UL /* user dirty (migration) */
423-
#define PGSTE_IN_BIT 0x0000400000000000UL /* IPTE notify bit */
424-
#define PGSTE_VSIE_BIT 0x0000200000000000UL /* ref'd in a shadow table */
422+
#define PGSTE_ST2_MASK 0x0000ffff00000000UL
423+
#define PGSTE_UC_BIT 0x0000000000008000UL /* user dirty (migration) */
424+
#define PGSTE_IN_BIT 0x0000000000004000UL /* IPTE notify bit */
425+
#define PGSTE_VSIE_BIT 0x0000000000002000UL /* ref'd in a shadow table */
425426

426427
/* Guest Page State used for virtualization */
427428
#define _PGSTE_GPS_ZERO 0x0000000080000000UL
@@ -2011,4 +2012,18 @@ extern void s390_reset_cmma(struct mm_struct *mm);
20112012
#define pmd_pgtable(pmd) \
20122013
((pgtable_t)__va(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE))
20132014

2015+
static inline unsigned long gmap_pgste_get_pgt_addr(unsigned long *pgt)
2016+
{
2017+
unsigned long *pgstes, res;
2018+
2019+
pgstes = pgt + _PAGE_ENTRIES;
2020+
2021+
res = (pgstes[0] & PGSTE_ST2_MASK) << 16;
2022+
res |= pgstes[1] & PGSTE_ST2_MASK;
2023+
res |= (pgstes[2] & PGSTE_ST2_MASK) >> 16;
2024+
res |= (pgstes[3] & PGSTE_ST2_MASK) >> 32;
2025+
2026+
return res;
2027+
}
2028+
20142029
#endif /* _S390_PAGE_H */

arch/s390/include/asm/uv.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,12 +628,12 @@ static inline int is_prot_virt_host(void)
628628
}
629629

630630
int uv_pin_shared(unsigned long paddr);
631-
int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
632-
int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
633631
int uv_destroy_folio(struct folio *folio);
634632
int uv_destroy_pte(pte_t pte);
635633
int uv_convert_from_secure_pte(pte_t pte);
636-
int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr);
634+
int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb);
635+
int uv_convert_from_secure(unsigned long paddr);
636+
int uv_convert_from_secure_folio(struct folio *folio);
637637

638638
void setup_uv(void);
639639

0 commit comments

Comments
 (0)